home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 329 / xatari.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-18  |  97.7 KB  |  3,954 lines

  1.  
  2. /***************************************************************************
  3.  
  4.     XATARI.C
  5.  
  6.     - Atari 800 service routines
  7.  
  8.     02/11/88 created
  9.     03/03/88 Laser C
  10.  
  11.     07/26/88 19:00
  12.  
  13. ***************************************************************************/
  14.  
  15. #include "xatari.h"
  16.  
  17. /* NMI, IRQ interrupts kept in separate bytes for easier checking of each */
  18.  
  19. /* bit masks for NMI interrupt byte (matches $D40E) */
  20. #define INT_DLI     0x80
  21. #define INT_VBI     0x40
  22. #define INT_RESET   0x20
  23.  
  24. #define BIT_DLI     7
  25. #define BIT_VBI     6
  26. #define BIT_RESET   5
  27.  
  28. /* bit masks for IRQ interrupt byte (matches $D20E) */
  29. #define INT_BREAK   0x80
  30. #define INT_KEY     0x40
  31. #define INT_4       0x04
  32. #define INT_2       0x02
  33. #define INT_1       0x01
  34.  
  35. #define BIT_BREAK   7
  36. #define BIT_KEY     6
  37. #define BIT_4       2
  38. #define BIT_2       1
  39. #define BIT_1       0
  40.  
  41. /* SIO return codes */
  42. #define SIO_OK      0x01
  43. #define SIO_TIMEOUT 0x8A
  44. #define SIO_NAK     0x8B
  45. #define SIO_DEVDONE 0x90
  46.  
  47. extern
  48.     rsB00(), rsB01(), rsB02(), rsB03(), rsB04(), rsB05(), rsB06(), rsB07(),
  49.     rsB08(), rsB09(), rsB0A(), rsB0B(), 
  50.     
  51.     rsPIA00(), rsPIA01(), rsPIA02(), rsPIA03(),
  52.  
  53.     rsGTIA00(), rsGTIA01(), rsGTIA02(), rsGTIA03(),
  54.     rsGTIA04(), rsGTIA05(), rsGTIA06(), rsGTIA07(),
  55.     rsGTIA08(), rsGTIA09(), rsGTIA0A(), rsGTIA0B(),
  56.     rsGTIA0C(), rsGTIA0D(), rsGTIA0E(), rsGTIA0F(),
  57.     rsGTIA10(), rsGTIA11(), rsGTIA12(), rsGTIA13(),
  58.     rsGTIA14(), rsGTIA15(), rsGTIA16(), rsGTIA17(),
  59.     rsGTIA18(), rsGTIA19(), rsGTIA1A(), rsGTIA1B(),
  60.     rsGTIA1C(), rsGTIA1D(), rsGTIA1E(), rsGTIA1F(),
  61.  
  62.     rsPOK00(), rsPOK01(), rsPOK02(), rsPOK03(),
  63.     rsPOK04(), rsPOK05(), rsPOK06(), rsPOK07(),
  64.     rsPOK08(), rsPOK09(), rsPOK0A(), rsPOK0B(),
  65.     rsPOK0C(), rsPOK0D(), rsPOK0E(), rsPOK0F(),
  66.  
  67.     rsANT00(), rsANT01(), rsANT02(), rsANT03(),
  68.     rsANT04(), rsANT05(), rsANT06(), rsANT07(),
  69.     rsANT08(), rsANT09(), rsANT0A(), rsANT0B(),
  70.     rsANT0C(), rsANT0D(), rsANT0E(), rsANT0F(),
  71.  
  72.     rsBXX(),
  73.  
  74.     wsB00(), wsB01(), wsB02(), wsB03(), wsB04(), wsB05(), wsB06(), wsB07(),
  75.     wsB08(), wsB09(), wsB0A(), wsB0B(),
  76.     
  77.     wsPIA00(), wsPIA01(), wsPIA02(), wsPIA03(),
  78.  
  79.     wsGTIA00(), wsGTIA01(), wsGTIA02(), wsGTIA03(),
  80.     wsGTIA04(), wsGTIA05(), wsGTIA06(), wsGTIA07(),
  81.     wsGTIA08(), wsGTIA09(), wsGTIA0A(), wsGTIA0B(),
  82.     wsGTIA0C(), wsGTIA0D(), wsGTIA0E(), wsGTIA0F(),
  83.     wsGTIA10(), wsGTIA11(), wsGTIA12(), wsGTIA13(),
  84.     wsGTIA14(), wsGTIA15(), wsGTIA16(), wsGTIA17(),
  85.     wsGTIA18(), wsGTIA19(), wsGTIA1A(), wsGTIA1B(),
  86.     wsGTIA1C(), wsGTIA1D(), wsGTIA1E(), wsGTIA1F(),
  87.  
  88.     wsPOK00(), wsPOK01(), wsPOK02(), wsPOK03(),
  89.     wsPOK04(), wsPOK05(), wsPOK06(), wsPOK07(),
  90.     wsPOK08(), wsPOK09(), wsPOK0A(), wsPOK0B(),
  91.     wsPOK0C(), wsPOK0D(), wsPOK0E(), wsPOK0F(),
  92.  
  93.     wsANT00(), wsANT01(), wsANT02(), wsANT03(),
  94.     wsANT04(), wsANT05(), wsANT06(), wsANT07(),
  95.     wsANT08(), wsANT09(), wsANT0A(), wsANT0B(),
  96.     wsANT0C(), wsANT0D(), wsANT0E(), wsANT0F(),
  97.     
  98.     wsDL0(), wsDL1(), wsDL2(), wsDL3(), wsDL4(), wsDL5(), wsDL6(), wsDL7(),
  99.     wsDL8(), wsDL9(), wsDLA(), wsDLB(), wsDLC(), wsDLD(), wsDLE(), wsDLF(),
  100.     
  101.     wsBXX();
  102.  
  103. extern enter_SIO(), vecSIO();
  104.  
  105. extern Atari_Hook(), Atari_Unhook(), LAtariVBI();
  106. extern LAtariInt();
  107.  
  108. extern oldKey(), KeyPatch(), semaJoy(), Joy0();
  109.  
  110. /* array of pointers to 256 service routines */
  111. void (*Bread_service[81])() =
  112.     {
  113.     rsB00, rsB01, rsB02, rsB03, rsB04, rsB05, rsB06, rsB07,
  114.     rsB08, rsB09, rsB0A, rsB0B,
  115.     
  116.     rsPIA00, rsPIA01, rsPIA02, rsPIA03,
  117.  
  118.     rsGTIA00, rsGTIA01, rsGTIA02, rsGTIA03,
  119.     rsGTIA04, rsGTIA05, rsGTIA06, rsGTIA07,
  120.     rsGTIA08, rsGTIA09, rsGTIA0A, rsGTIA0B,
  121.     rsGTIA0C, rsGTIA0D, rsGTIA0E, rsGTIA0F,
  122.     rsGTIA10, rsGTIA11, rsGTIA12, rsGTIA13,
  123.     rsGTIA14, rsGTIA15, rsGTIA16, rsGTIA17,
  124.     rsGTIA18, rsGTIA19, rsGTIA1A, rsGTIA1B,
  125.     rsGTIA1C, rsGTIA1D, rsGTIA1E, rsGTIA1F,
  126.  
  127.     rsPOK00, rsPOK01, rsPOK02, rsPOK03,
  128.     rsPOK04, rsPOK05, rsPOK06, rsPOK07,
  129.     rsPOK08, rsPOK09, rsPOK0A, rsPOK0B,
  130.     rsPOK0C, rsPOK0D, rsPOK0E, rsPOK0F,
  131.  
  132.     rsANT00, rsANT01, rsANT02, rsANT03,
  133.     rsANT04, rsANT05, rsANT06, rsANT07,
  134.     rsANT08, rsANT09, rsANT0A, rsANT0B,
  135.     rsANT0C, rsANT0D, rsANT0E, rsANT0F,
  136.     
  137.     rsBXX
  138.     };
  139.  
  140. void (*Bwrite_service[97])() =
  141.     {
  142.     wsB00, wsB01, wsB02, wsB03, wsB04, wsB05, wsB06, wsB07,
  143.     wsB08, wsB09, wsB0A, wsB0B,
  144.     
  145.     wsPIA00, wsPIA01, wsPIA02, wsPIA03,
  146.  
  147.     wsGTIA00, wsGTIA01, wsGTIA02, wsGTIA03,
  148.     wsGTIA04, wsGTIA05, wsGTIA06, wsGTIA07,
  149.     wsGTIA08, wsGTIA09, wsGTIA0A, wsGTIA0B,
  150.     wsGTIA0C, wsGTIA0D, wsGTIA0E, wsGTIA0F,
  151.     wsGTIA10, wsGTIA11, wsGTIA12, wsGTIA13,
  152.     wsGTIA14, wsGTIA15, wsGTIA16, wsGTIA17,
  153.     wsGTIA18, wsGTIA19, wsGTIA1A, wsGTIA1B,
  154.     wsGTIA1C, wsGTIA1D, wsGTIA1E, wsGTIA1F,
  155.  
  156.     wsPOK00, wsPOK01, wsPOK02, wsPOK03,
  157.     wsPOK04, wsPOK05, wsPOK06, wsPOK07,
  158.     wsPOK08, wsPOK09, wsPOK0A, wsPOK0B,
  159.     wsPOK0C, wsPOK0D, wsPOK0E, wsPOK0F,
  160.  
  161.     wsANT00, wsANT01, wsANT02, wsANT03,
  162.     wsANT04, wsANT05, wsANT06, wsANT07,
  163.     wsANT08, wsANT09, wsANT0A, wsANT0B,
  164.     wsANT0C, wsANT0D, wsANT0E, wsANT0F,
  165.     
  166.     wsDL0, wsDL1, wsDL2, wsDL3, wsDL4, wsDL5, wsDL6, wsDL7,
  167.     wsDL8, wsDL9, wsDLA, wsDLB, wsDLC, wsDLD, wsDLE, wsDLF,
  168.     
  169.     wsBXX
  170.     };
  171.  
  172. /* used for the sound emulation */
  173. char rgbSound[9];
  174.  
  175. /* tells us if a disk drive is attached */
  176. int fDOS = FALSE;
  177. /* this is the DOS 2.0 disk emulation buffer */
  178. long lrgbDrive;
  179.  
  180. extern long lFreeSpace;
  181.  
  182. int fAtariXLROMs;       /* Atari XL ROMs selected? */
  183. int fAtariXL;           /* bank select hardware enabled? */
  184. int fFastIO;            /* fast disk I/O? */
  185. int fFastFP;            /* is Fastchip selected? */
  186. int fAtCart;            /* is a cartridge plugged in */
  187. unsigned int uAtRAM;    /* byte past end of RAM ($8000, $A000, $C000) */
  188. long    lrgbXLRAM;
  189. int     fXLRAM;
  190. int wVBIrate, wVBIcount;
  191.  
  192. /* paths and names of 2 drive files */
  193. ATARIDRIVE rgAD[2];
  194.  
  195. /* definitions of D1: and D2: */
  196. SECTOR *rgsectors[2];
  197. int fDDenable;           /* enough memory to support DD? */
  198.  
  199. /*************************************************************************/
  200.         
  201. /* init Atari for the first time */
  202. init_atari()
  203.     {
  204.     int w;
  205.     register ATARIDRIVE *pAD;
  206.     
  207.     w = Dgetdrv();
  208.  
  209.     pAD = &rgAD[0];
  210.     pAD->rgchPath[0] = 'A' + w;
  211.     pAD->rgchPath[1] = ':';
  212.     Dgetpath(&pAD->rgchPath[2], 0);
  213.     pAD->rgchName[0] = 0;
  214.     pAD->mdDensity = 0;
  215.  
  216.     pAD++;
  217.     pAD->rgchPath[0] = 'A' + w;
  218.     pAD->rgchPath[1] = ':';
  219.     Dgetpath(&pAD->rgchPath[2], 0);
  220.     pAD->rgchName[0] = 0;
  221.     pAD->mdDensity = 0;
  222.  
  223.     lrgbDrive = lFreeSpace;
  224.     rgsectors[0] = (SECTOR *)lrgbDrive;
  225.     rgsectors[1] = rgsectors[0] + 720;
  226.     
  227.     lrgbXLRAM = lRStat - 16384L;
  228.     fXLRAM  = 0;
  229.     
  230.     wVBIrate = 1;
  231.     }
  232.  
  233.  
  234. /* initialize the stat arrays and set defaults for power on */
  235. setup_atari()
  236.     {
  237.     register unsigned ea;
  238.     register int x,y;
  239.     register char *qRStat = (char *)lRStat;
  240.     register char *qWStat = (char *)lWStat;
  241.     register int h;
  242.  
  243.     fRedraw = FALSE;    /* let DL take care of it */
  244.     fPMGRedraw = FALSE;
  245.     fAtDMA = FALSE;
  246.     mdAtWidth = 0;
  247.     uAtCharBase = 0;
  248.     bDMACTL = 0;
  249.     mdAtWidth = 0;
  250.     uDLStart = 0;
  251.     wVBIcount = 0;
  252.     fXLRAM  = 0;
  253.  
  254.     /* clear sound regs */
  255.     Blitzb(rgbSound, 9);
  256.  
  257.     /* clear color regs */
  258.     Blitzb(rgwAtColors, 9);
  259.  
  260.     /* clear video display */
  261.     Blitzl(lScr, 10240);
  262.  
  263.     /* clear out read stat array */
  264.     Blitzl(qRStat - 32768L, 8192);
  265.     /* write protect upper half of memory */
  266.     Blitc(0x80, qWStat - 32768L, 32768);
  267.     /* un-write protect lower half of memory */
  268.     Blitc(0x00, qWStat, 32768);
  269.  
  270.     /* now set up RAM and ROM */        
  271.     if (fAtCart && (uAtRAM==49152))
  272.         uAtRAM = 40960;
  273.  
  274.     if (uAtRAM > 32768)
  275.         Blitc(0x00, qWStat - 32768L, uAtRAM - 32768); 
  276.  
  277.     /* set status bytes for POKEY, ANTIC, PIA, and GTIA chips */
  278.     {
  279.     int i;
  280.     
  281.     if (fAtariXL)   /* is bank switching enabled? */
  282.         {
  283.         for (i = 0; i < 16384; i++)
  284.             {
  285.             qWStat[0xFFFFC000+i] = 0x81;
  286.             }
  287.         }
  288.  
  289.     for (i=0; i<256; i++)
  290.         {
  291.         qRStat[0xFFFFD000+i] = 16 + (i & 0x1F);     /* GTIA */
  292.         qRStat[0xFFFFD200+i] = 48 + (i & 0x0F);     /* POKEY */
  293.         qRStat[0xFFFFD300+i] = 12 + (i & 0x03);     /* PIA */
  294.         qRStat[0xFFFFD400+i] = 64 + (i & 0x0F);     /* ANTIC */
  295.  
  296.         qWStat[0xFFFFD000+i] = 0x80 + 16 + (i & 0x1F);     /* GTIA */
  297.         qWStat[0xFFFFD200+i] = 0x80 + 48 + (i & 0x0F);     /* POKEY */
  298.         qWStat[0xFFFFD300+i] = 0x80 + 12 + (i & 0x03);     /* PIA */
  299.         qWStat[0xFFFFD400+i] = 0x80 + 64 + (i & 0x0F);     /* ANTIC */
  300.         }
  301.     }
  302.  
  303.     {
  304.     int iHeap = 0;
  305.     long lToRS, lToWS;
  306.     long lFromRS, lFromWS, lNextRS, lNextWS;
  307.     int iService = 0;
  308.  
  309.     /* blit the 81 read and 97 write routines */
  310.     do
  311.         {
  312.         if (iService < 80)
  313.             {
  314.             lToRS = lEmul + iHeap + (int)iRead;
  315.             lFromRS = (long)Bread_service[iService];
  316.             lNextRS = (long)Bread_service[iService+1];
  317.     
  318.             Assert(((int)(lNextRS - lFromRS)) >= 0, "RS blitting negative");
  319.             Assert(((int)(lNextRS - lFromRS)) != 0, "RS blitting 0");
  320.             Assert(((int)(lNextRS - lFromRS)) < 128, "RS blitting >128");
  321.         
  322.             Blitb(lFromRS, lToRS, (int)(lNextRS - lFromRS));
  323.             }
  324.  
  325.         lToWS = lEmul + iHeap + (int)iWrite;
  326.         lFromWS = (long)Bwrite_service[iService];
  327.         lNextWS = (long)Bwrite_service[iService+1];
  328.  
  329.         Assert(((int)(lNextWS - lFromWS)) >= 0, "WS blitting negative");
  330.         Assert(((int)(lNextWS - lFromWS)) != 0, "WS blitting 0");
  331.         Assert(((int)(lNextWS - lFromWS)) < 128, "WS blitting >128");
  332.         
  333.         Blitb(lFromWS, lToWS, (int)(lNextWS - lFromWS));
  334.  
  335. #ifdef NDEBUG
  336.         printf("%3d lEmul = $%5lx    lToRS = $%5lx   lToWS = $%5lx\n",
  337.             iService, lEmul, lToRS, lToWS);
  338. #endif
  339.         iHeap += 256;
  340.         iService++;
  341.         } while (iService != 96);
  342.     }
  343.  
  344.     /* opcode $80 becomes the SIO entry point */
  345.     Blitb(vecSIO, lEmul - 0x00008000L + 6L, 64);
  346.  
  347.     /* fill RAM with a random value ($AA) - mustn't be $FF */
  348.     Blitc(0xAA, lMemory, 0xC000);
  349.     
  350.     /* fill hardware registers with $00 */
  351.     Blitc(0, lMemory + (unsigned)0xD000, 0x0800);
  352.     
  353.     if (fAtCart)
  354.         Blitb(LAtariBasic,lMemory + (unsigned)0xA000,8192);
  355.  
  356.     if (fAtariXLROMs)
  357.         {
  358.         Blitb(LAtariXL,lMemory+(unsigned)0xD800,10240);
  359.         Blitb(LAtariXL2,lMemory+(unsigned)0xC000,4096);
  360.         Poke (0xFC87, 0xEA); Poke (0xFC88, 0xEA); Poke (0xFC89, 0xEA); 
  361.         Poke (0xC410, 0xEA); Poke (0xC411, 0xEA); Poke (0xC412, 0xEA); 
  362.         Poke (0xEEFF, 0xEA); Poke (0xEF00, 0xEA); Poke (0xEF01, 0xEA); 
  363.         Poke (0xEF02, 0xEA); Poke (0xEF03, 0xEA);
  364.         Poke (0xC30B, 0x4C); Poke (0xC30C, 0x27); Poke (0xC30D, 0xC3); 
  365.         Poke (0xC3AB, 0x4C); Poke (0xC3AC, 0xC4); Poke (0xC3AD, 0xC3); 
  366.         Poke (0xC4ED, 0xEA); Poke (0xC4EE, 0xEA); Poke (0xC4EF, 0xEA); 
  367.         Poke (0xC67B, 0x60);
  368.         }
  369.     else
  370.         Blitb(LAtariFP,lMemory+(unsigned)0xD800,10240);
  371.  
  372.     if (fFastFP)
  373.         Blitb(LFastFP,lMemory+(unsigned)0xD800,2048);
  374.  
  375.     /* patch SIO vector */
  376.     h = Dpeek(0xE45A);
  377.     Poke(h, 0x80);
  378.     Poke(h+1, 0x60);
  379.     
  380.     pHookIn = Atari_Hook;
  381.     pUnHook = Atari_Unhook;
  382.     
  383. #ifdef NDEBUG
  384.     printf("setup_atari(): pHookIn = $%5lx   pUnHook = $%5lx\n",
  385.         pHookIn, pUnHook);
  386. #endif
  387.  
  388.     /* install interrupt handler */
  389.     *(int *)(lEmul + (lInterrupt)) = OP_JMP;
  390.     *(long *)(lEmul + (lIntVec)) = (long)LAtariInt;
  391.     }
  392.  
  393. /*************************************************************************/
  394.  
  395. DTA *qdta;
  396.  
  397. /* load specified file */
  398. int atari_load(mdDrive)
  399. int mdDrive;
  400.     {
  401.     register char *pch;
  402.     int h;
  403.     long liDrive;   /* for multiple drive support */
  404.     ATARIDRIVE *qAD;
  405.     long lcb;
  406.  
  407. #ifdef NDEBUG
  408.     printf("Atari_load()\n");
  409.     printf("mdDrive = %d\n", mdDrive);
  410. #endif
  411.  
  412.     liDrive = ((mdDrive) ? (fDDenable ? 184320L : 92160L) : 0L);
  413.  
  414.     if (mdDrive == 0)
  415.         fDOS = FALSE;
  416.  
  417.     qAD = &rgAD[mdDrive];
  418.     qAD->mdDensity = 0;
  419.  
  420. #ifdef NDEBUG    
  421.     printf("path = %s\n", qAD->rgchPath);
  422.     printf("name = %s\n", qAD->rgchName);
  423. #endif
  424.     qAD->rgchPath[70] = 0;
  425.  
  426.     pch = &qAD->rgchPath[0];
  427.     
  428.     if (pch[1] != ':' || pch[2] != '\\')
  429.         return;
  430.         
  431.     pch += strlen(pch);
  432.  
  433.     while (--pch > &qAD->rgchPath[2])
  434.         {
  435.         if (*pch == '*' || *pch == '?')
  436.             {
  437.             while (*--pch != '\\')
  438.                 ;
  439.             *pch = 0;
  440.             break;
  441.             }
  442.         else if (*pch == '\\')
  443.             break;
  444.         }
  445.     *++pch = 0;
  446.     qAD->rgchPath[2] = '\\';
  447.     
  448.     Dsetdrv(qAD->rgchPath[0]-'A');
  449.  
  450.     if (Dsetpath(&qAD->rgchPath[2]) < 0)
  451.         return;
  452.  
  453.     /* finally load a disk */
  454.     h = Fopen(qAD->rgchName,0);
  455.     if (h>=0)
  456.         {
  457.         lcb = Fread(h, mdDrive ? 92161L : 184321L, lrgbDrive + liDrive);
  458.         Fclose(h);
  459.         if (mdDrive == 0)
  460.             fDOS = TRUE;
  461.         if ((lcb == 184320L) && fDDenable)
  462.             qAD->mdDensity = 3;
  463.         else if (lcb == 92160L)
  464.             qAD->mdDensity = 1;
  465.         else
  466.             {
  467.             Bconout(2,7);
  468.             qAD->mdDensity = 0;
  469.             fDOS = FALSE;
  470.             }
  471.         }
  472.     }
  473.  
  474. /* save specified file */
  475. int atari_save(mdDrive)
  476. int mdDrive;
  477.     {
  478.     register char *pch;
  479.     int h;
  480.     long liDrive;   /* for multiple drive support */
  481.     ATARIDRIVE *qAD;
  482.  
  483. #ifdef NDEBUG
  484.     printf("Atari_save()\n");
  485.     printf("mdDrive = %d\n", mdDrive);
  486. #endif
  487.  
  488.     liDrive = ((mdDrive) ? (fDDenable ? 184320L : 92160L) : 0L);
  489.  
  490.     qAD = &rgAD[mdDrive];
  491.  
  492. #ifdef NDEBUG    
  493.     printf("path = %s\n", qAD->rgchPath);
  494.     printf("name = %s\n", qAD->rgchName);
  495. #endif
  496.     qAD->rgchPath[70] = 0;
  497.     
  498.     pch = &qAD->rgchPath[0];
  499.     
  500.     if (pch[1] != ':' || pch[2] != '\\')
  501.         return;
  502.         
  503.     pch += strlen(pch);
  504.  
  505.     while (--pch > &qAD->rgchPath[2])
  506.         {
  507.         if (*pch == '*' || *pch == '?')
  508.             {
  509.             while (*--pch != '\\')
  510.                 ;
  511.             *pch = 0;
  512.             break;
  513.             }
  514.         else if (*pch == '\\')
  515.             break;
  516.         }
  517.     *++pch = 0;
  518.     qAD->rgchPath[2] = '\\';
  519.     
  520.     Dsetdrv(qAD->rgchPath[0]-'A');
  521.  
  522.     if (Dsetpath(&qAD->rgchPath[2]) < 0)
  523.         return;
  524.  
  525.     /* finally save a disk */
  526.     h = Fcreate(qAD->rgchName,0);
  527.     if (h>=0)
  528.         {
  529.         if (qAD->mdDensity == 3)
  530.             Fwrite(h, 184320L, lrgbDrive + liDrive);
  531.         else
  532.             Fwrite(h, 92160L, lrgbDrive + liDrive);
  533.         Fclose(h);
  534.         }
  535.     }
  536.  
  537. atari_dir(wDrive)
  538. register unsigned wDrive;     /* 0 = D1:   1 = D2: */
  539.     {
  540.     register unsigned iFile;
  541.     register unsigned cFiles = 1;   /* init to 1 to skip title */
  542.     register unsigned cSectors=0;
  543.     register DIRENTRY *rgDirEntry = (DIRENTRY *)&rgsectors[wDrive][0x168];
  544.     register rgch[20];
  545.     int fDD=FALSE;
  546.  
  547.     Assert(wDrive < 2, "wDrive too large");
  548.  
  549.     printf("\033EDirectory of D%c:\n", wDrive + '1');
  550.  
  551.     if (rgAD[wDrive].mdDensity == 0)
  552.         {
  553.         printf("\n\nDisk drive is empty!!\n\n");
  554.         goto LexitDir;
  555.         }
  556.     else if (rgAD[wDrive].mdDensity == 3)
  557.         {
  558.         fDD = TRUE;
  559.         rgDirEntry = (DIRENTRY *)&rgsectors[wDrive][0x168 + 0x168];
  560.         }
  561.  
  562.     if (free_secs(wDrive) == -1)
  563.         {
  564.         printf("\n\nDisk full or not a DOS disk\n\n");
  565.         goto LexitDir;
  566.         }
  567.  
  568.     for (iFile = 0; iFile<64; iFile++)
  569.         {
  570.         if (!(rgDirEntry->rgf & fInUse))
  571.             continue;
  572.  
  573.         Blitb(rgDirEntry->rgchName, rgch, 11);
  574.         rgch[11] = 0;
  575.         
  576.         printf("\033Y%c%c", 32 + 1 + cFiles%22, 32 + 2 + (cFiles/22)*24);
  577.         printf("%11.11s %03d\n", rgch,
  578.             rgDirEntry->cSizeL + 256*rgDirEntry->cSizeH);
  579.         cSectors += rgDirEntry->cSizeL + 256*rgDirEntry->cSizeH;
  580.         cFiles++;
  581.         rgDirEntry++;
  582.         if (fDD && ((iFile & 7) == 7))
  583.             rgDirEntry += 8;
  584.         }
  585.     printf("\033Y%c%c", 32 + 24, 32);
  586.     printf("%4d free sectors", free_secs(wDrive));
  587.  
  588.     if (fDD)
  589.         printf("  double density");
  590.  
  591. LexitDir:  
  592.     printf("\033Y%c%cPress any key to continue...", 32 + 24, 32 + 40);
  593.     fflush(stdout);
  594.     Bconin(2);
  595.     }
  596.  
  597. int free_secs(wDrive)
  598. int wDrive;
  599.     {
  600.     unsigned isec;
  601.     unsigned csec=0;
  602.     
  603. /* 0 - 0 = DOS 2.0 flag
  604.    1,2 - total sectors (707)
  605.    3,4 - number of unused sectors
  606. */
  607.     if (rgAD[wDrive].mdDensity == 0)
  608.         return 0;
  609.  
  610.     for (isec=1; isec<=719; isec++)
  611.         {
  612.         if (mark_sec(isec, -1, wDrive))
  613.             csec++;
  614.         }
  615.     return csec;
  616.     }
  617.  
  618. int mark_sec(isec, md, wDrive)
  619. unsigned isec;
  620. int md, wDrive;
  621.     {
  622.     VTC *vtc = (VTC *)&rgsectors[wDrive][0x167];
  623.     unsigned bOld;
  624.  
  625.     if (rgAD[wDrive].mdDensity == 3)
  626.         vtc = (VTC *)&rgsectors[wDrive][0x167 + 0x167];
  627.  
  628.     bOld = (vtc->rgchBits[isec>>3] >> (7-(isec&0x7))) & 1;
  629.  
  630.     if (md == -1)
  631.         return bOld;
  632.  
  633.     if (md == 1)
  634.         vtc->rgchBits[isec>>3] |= (1 << (7-(isec&0x7)));
  635.     else
  636.         vtc->rgchBits[isec>>3] &= ~(1 << (7-(isec&0x7)));
  637.  
  638.     return bOld;
  639.     }
  640.  
  641. int addfile(wDrive)
  642. register int wDrive;
  643.     {
  644.     int iFile;
  645.     int hFile;
  646.     char *pchPath = rgAD[wDrive].rgchPath;
  647.     char *pch = rgAD[wDrive].rgchName;
  648.     unsigned secFree, secNext;
  649.     long cch, csecFile;
  650.     register DIRENTRY *rgDirEntry = (DIRENTRY *)&rgsectors[wDrive][0x168];
  651.  
  652.     for (iFile = 0; iFile<64; iFile++)
  653.         {
  654.         if ((rgDirEntry[iFile].rgf & 0x7F) == 0)
  655.             break;
  656.         }
  657.         
  658.     if (iFile == 64)
  659.         {
  660.         form_alert(1, "[0][ Directory full!! ][ OK ]");
  661.         return;
  662.         }
  663.  
  664.     secNext = 4;
  665.     while (mark_sec(secNext,-1, wDrive) == 0)
  666.         secNext++;
  667.  
  668. #ifdef NDEBUG    
  669.     printf("Opening %s\n", pch);
  670. #endif
  671.     
  672.     if ((hFile = Fopen(pch,0)) < 0)
  673.         {
  674.         form_alert(1, "[0][ Couldn't open file ][ OK ]");
  675.         return;
  676.         }  
  677.  
  678.     cch = Fseek(0L, hFile, 2);
  679.     csecFile = (cch+124L)/125L;
  680.     Fclose(hFile);
  681.  
  682.     if (csecFile > free_secs(wDrive))
  683.         {
  684.         form_alert(1, "[0][ File too large!! ][ OK ]");
  685.         return;
  686.         }  
  687.  
  688. #ifdef NDEBUG        
  689.     printf("File size = %ld\n", cch);
  690. #endif
  691.  
  692.     hFile = Fopen(pch,0);
  693.  
  694.     fn_expand(pch, rgDirEntry[iFile].rgchName);   
  695.     rgDirEntry[iFile].cSizeL = (unsigned char)(csecFile);   
  696.     rgDirEntry[iFile].cSizeH = (unsigned char)(csecFile >> 8);   
  697.     rgDirEntry[iFile].cStartL = (unsigned char)(secNext);        
  698.     rgDirEntry[iFile].cStartH = (unsigned char)(secNext >> 8);
  699.     rgDirEntry[iFile].rgf = (fDos20 | fInUse);
  700.  
  701.     while (cch > 125L)
  702.         {
  703.         secFree = secNext;
  704.         mark_sec(secFree,0, wDrive);
  705.         while (mark_sec(secNext,-1, wDrive) == 0)
  706.             secNext++;
  707.  
  708. #ifdef NDEBUG        
  709.         printf("copying 125 bytes to sector %d, next free = %d\n",
  710.             secFree, secNext);
  711. #endif
  712.  
  713.         secFree--;
  714.         if (Fread(hFile, 125L, rgsectors[wDrive][secFree].rgchData) < 0)
  715.             {
  716.             form_alert(1, "[0][ Error reading!! ][ OK ]");
  717.             }
  718. #ifdef NDEBUG
  719.         printf("Data read at %06lx\n", rgsectors[wDrive][secFree].rgchData);
  720.         printf("data = %02x %02x %02x %02x\n",
  721.             rgsectors[wDrive][secFree].rgchData[0],
  722.             rgsectors[wDrive][secFree].rgchData[1],
  723.             rgsectors[wDrive][secFree].rgchData[2],
  724.             rgsectors[wDrive][secFree].rgchData[3]);
  725. #endif
  726.  
  727.         rgsectors[wDrive][secFree].ucBytes = 125;
  728.         rgsectors[wDrive][secFree].uFileNum = iFile;
  729.         rgsectors[wDrive][secFree].uSectorL = secNext & 0xFF;
  730.         rgsectors[wDrive][secFree].uSectorH = secNext >> 8;
  731.         cch -= 125L;
  732.         }
  733.         
  734. #ifdef NDEBUG
  735.     printf("copying %d bytes to last sector %d, next free = %d\n",
  736.         (unsigned)cch, secFree, secNext);
  737. #endif
  738.  
  739.     secFree = secNext;
  740.     mark_sec(secFree,0, wDrive);
  741.     secFree--;
  742.     Fread(hFile, cch, rgsectors[wDrive][secFree].rgchData);
  743.     rgsectors[wDrive][secFree].ucBytes = (unsigned)cch;
  744.     rgsectors[wDrive][secFree].uFileNum = iFile;
  745.     rgsectors[wDrive][secFree].uSectorL = 0;
  746.     rgsectors[wDrive][secFree].uSectorH = 0;
  747.  
  748.     /* update free sectors on disk */
  749.     ((VTC *)&rgsectors[wDrive][0x167])->foo[3] = free_secs(wDrive) & 0xFF;
  750.     ((VTC *)&rgsectors[wDrive][0x167])->foo[4] = (free_secs(wDrive) >> 8);
  751.     
  752.     Fclose(hFile);
  753.  
  754.     form_alert(1, "[0][ File transferred ][ OK ]");
  755.     }
  756.  
  757. /* convert filename in *.* format to ??????????? format */
  758. fn_expand(pch, rgchFile)
  759. char *pch, *rgchFile;
  760.     {
  761.     unsigned ich=0;
  762.  
  763.     Blitc(' ', rgchFile, 11);
  764.     
  765.     while (*pch != '.' && ich<8)
  766.         {
  767.         if (*pch == 0)
  768.             return;
  769.         rgchFile[ich++] = toupper(*pch++);
  770.         }
  771.  
  772.     if (*pch != '.')
  773.         return;
  774.  
  775.     ich = 8;
  776.     pch++;
  777.  
  778.     while (*pch && ich<11)
  779.         {
  780.         rgchFile[ich++] = toupper(*pch++);
  781.         }
  782.     }
  783.  
  784. char b484Sav;
  785.  
  786. /* This hooks all the interrupt vectors and also does anything that should
  787. ** be done, like clearing console keys, etc.
  788. */
  789.  
  790. Atari_Hook()
  791.     {
  792. #ifdef NDEBUG
  793.     printf("Atari_Hook()\n");
  794. #endif
  795.  
  796.     b484Sav = *(char *)0x0484L;
  797.     *(char*)0x0484L &= ~3;      /* disable keyclick */
  798.     
  799.     VBI_on(LAtariVBI);
  800.     Install_Key();
  801.  
  802.     Setpalette(rgwAtColors);    
  803.     Poke (0xD01F,7);
  804.     }
  805.     
  806. Atari_Unhook()
  807.     {
  808.     Remove_Key();
  809.     VBI_off();
  810.     *(char*)0x0484L = b484Sav;  /* enable keyclick */
  811.  
  812.     Setpalette(rgwPalette);    
  813.  
  814. #ifdef NDEBUG
  815.     printf("Atari_UnHook()\n");
  816. #endif
  817.     }
  818.  
  819. Install_Key()
  820.     {
  821.     register long *qKbdvBase;
  822.  
  823.     qKbdvBase = (long *) Kbdvbase();
  824.  
  825. asm
  826.     {
  827.     ; turn off mouse     = Bconout(4,$12)
  828.     move.w  #0x12,-(A7)
  829.     move.w  #4,-(A7)
  830.     move.w  #3,-(A7)
  831.     trap    #13
  832.     addq.l  #6,A7
  833.  
  834.     ; get old keyboard vector
  835.     move.l  32(qKbdvBase),oldKey
  836.     lea     KeyPatch,A1
  837.     move.l  A1,32(qKbdvBase)
  838.  
  839.     ; turn on joysticks = Bconout(4,$14)
  840.     move.w  #0x14,-(A7)
  841.     move.w  #4,-(A7)
  842.     move.w  #3,-(A7)
  843.     trap    #13
  844.     addq.l  #6,A7
  845.     }
  846.     }
  847.  
  848. Remove_Key()
  849.     {
  850.     register long *qKbdvBase;
  851.  
  852.     qKbdvBase = (long *)Kbdvbase();
  853.  
  854. asm {
  855.     ; turn off joysticks = Bconout(4,$1A)
  856.     move.w  #0x1a,-(A7)
  857.     move.w  #4,-(A7)
  858.     move.w  #3,-(A7)
  859.     trap    #13
  860.     addq.l  #6,A7
  861.     
  862.     move.l  oldKey,32(qKbdvBase)     ; recover the old keyboard vector
  863.  
  864.     ; turn on mouse      = Bconout(4,$8)
  865.     move.w  #0x8,-(A7)
  866.     move.w  #4,-(A7)
  867.     move.w  #3,-(A7)
  868.     trap    #13
  869.     addq.l  #6,A7
  870.     }
  871.     }
  872.  
  873.  
  874. /************************* End of init code ********************/
  875.  
  876. enter_SIO()
  877.     {
  878.     int wDev, wDrive, wCom, wStat, wBuff, wBytes, wSector, bAux1, bAux2;
  879.     int wRetStat = SIO_OK;
  880.     long liDrive;   /* for multiple drive support */
  881.  
  882. #ifdef NDEBUG
  883.     printf("\033HDevice ID = %2x\n", Peek(0x300));
  884.     printf("Drive # = %2x\n", Peek(0x301));
  885.     printf("Command = %2x\n", Peek(0x302));
  886.     printf("SIO Command = %2x\n", Peek(0x303));
  887.     printf("Buffer = %2x\n", Dpeek(0x304));
  888.     printf("Timeout = %2x\n", Dpeek(0x306));
  889.     printf("Byte count = %2x\n", Dpeek(0x308));
  890.     printf("Sector = %2x\n", Dpeek(0x30A));
  891.     printf("Aux1 = %2x\n", Peek(0x30A));
  892.     printf("Aux2 = %2x\n", Peek(0x30B));
  893. #endif
  894.  
  895.     wDev = Peek(0x300);
  896.     wDrive = Peek(0x301);
  897.     wCom = Peek(0x302);
  898.     wStat = Peek(0x303);
  899.     wBuff = Dpeek(0x304);
  900.     wBytes = Dpeek(0x308);
  901.     wSector = Dpeek(0x30A)-1;
  902.     bAux1 = Peek(0x30A);
  903.     bAux2 = Peek(0x30B);
  904.     
  905.     switch (wDev)
  906.         {
  907.     default:
  908. #ifdef NDEBUG
  909.         printf("SIO: wDev = %2x  wCom = %2x  wBytes = %2x\n",
  910.             wDev, wCom, wBytes);
  911.         printf("SIO: wBuff = %4x  bAux1 = %2x  bAux2 = %2x\n",
  912.             wBuff, bAux1, bAux2);
  913. #endif
  914.         wRetStat = SIO_TIMEOUT;
  915.         break;
  916.         
  917.     case 0x40:
  918.         {
  919. #ifdef NDEBUG
  920.         printf("SIO: wDev = %2x  wCom = %2x  wBytes = %2x\n",
  921.             wDev, wCom, wBytes);
  922.         printf("SIO: wBuff = %4x  bAux1 = %2x  bAux2 = %2x\n",
  923.             wBuff, bAux1, bAux2);
  924. #endif
  925.         switch(wCom)
  926.             {
  927.         /* status request */
  928.         case 'S': 
  929.             break;
  930.             
  931.         case 'W':
  932.             /* print line */
  933.             {
  934.             int timeout;
  935.             char *pchBuf = (char *)lMemory + (unsigned)wBuff;
  936.             int  cch = wBytes;
  937.  
  938.             while ((pchBuf[cch-1] == ' ') && (cch>0))
  939.                 cch--;
  940.  
  941.             while ((cch-- > 0) && (wRetStat == SIO_OK))
  942.                 {
  943.                 for (timeout = 1000; timeout > 0; timeout--)
  944.                     {
  945.                     if (Cprnos())
  946.                         {                       /* if printer is ready */
  947.                         if (*pchBuf != (char)0x9B)
  948.                             Cprnout (*pchBuf++); /* check for CR and print */
  949.                         else
  950.                             {
  951.                             pchBuf++;
  952.                             Cprnout(13);     
  953.                             Cprnout(10);
  954.                             }
  955.                         wRetStat = SIO_OK;
  956.                         break;
  957.                         }
  958.                     wRetStat = SIO_TIMEOUT;  /* else status = timeout error */
  959.                     }
  960.                 }
  961.             }
  962.             }
  963.         }
  964.         break;
  965.  
  966.     case 0x31:
  967.     case 0x32:
  968.         {
  969.         int fDD = (rgAD[wDrive-1].mdDensity == 3);
  970.  
  971.         if (!fDOS || (rgAD[wDrive-1].mdDensity == 0))
  972.             {
  973.             wRetStat = 0x8A;    /* device doesn't respond error */
  974.             break;
  975.             }
  976.  
  977.         liDrive = ((wDrive-1) ? (fDDenable ? 184320L : 92160L) : 0L);
  978.  
  979.         switch(wCom)
  980.             {
  981.         /* format enhanced density */
  982.         case '"':
  983.             wRetStat = SIO_NAK;
  984.             break;
  985.   
  986.         case '!':
  987.             if (rgAD[wDrive-1].fWP)     /* is drive write-protected? */
  988.                 {
  989.                 wRetStat = SIO_DEVDONE;
  990.                 break;
  991.                 }
  992.  
  993.             /* "format" disk, just zero all sectors */
  994.             Blitzl(lrgbDrive + liDrive, fDD ? 46080 : 23040);
  995.             break;
  996.  
  997.         /* status request */
  998.         case 'S':
  999.             /* b7 = enhanced   b5 = DD/SD  b4 = motor on   b3 = write prot */
  1000.             Poke (wBuff++, (fDD ? 32 : 0) + (rgAD[wDrive-1].fWP ? 8 : 0));
  1001.  
  1002.             Poke (wBuff++, 0xFF);         /* controller */
  1003.             Poke (wBuff++, 0xE0);         /* format timeout */
  1004.             Poke (wBuff, 0x00);           /* unused */
  1005.             break;
  1006.             
  1007.         /* get configuration */
  1008.         case 'N':
  1009.             Poke (wBuff++, 0x28);         /* tracks */
  1010.             Poke (wBuff++, 0x02);         /* ?? */
  1011.             Poke (wBuff++, 0x00);         /* ?? */
  1012.             Poke (wBuff++, 0x12);         /* sectors/track */
  1013.             Poke (wBuff++, 0x00);         /* ?? */
  1014.  
  1015.             if (rgAD[wDrive-1].mdDensity == 3)
  1016.                 {
  1017.                 Poke (wBuff++, 0x04);     /* density: 4 = dbl  0 = sng */
  1018.                 Poke (wBuff++, 0x01);     /* bytes/sector hi */
  1019.                 Poke (wBuff++, 0x00);     /* bytes/sector lo */
  1020.                 }
  1021.             else
  1022.                 {
  1023.                 Poke (wBuff++, 0x00);     /* density: 4 = dbl  0 = sng */
  1024.                 Poke (wBuff++, 0x00);     /* bytes/sector hi */
  1025.                 Poke (wBuff++, 0x80);     /* bytes/sector lo */
  1026.                 }
  1027.             Poke (wBuff++, 0xFF);         /* unused */
  1028.             Poke (wBuff++, 0xFF);         /* unused */
  1029.             Poke (wBuff++, 0xFF);         /* unused */
  1030.             Poke (wBuff, 0xFF);           /* unused */
  1031.             break;
  1032.  
  1033.         /* set configuration */
  1034.         case 'O':
  1035.             if (Peek(wBuff + 5) == 4)
  1036.                 {
  1037.                 rgAD[wDrive-1].mdDensity = 3;
  1038.                 }
  1039.             else
  1040.                 {
  1041.                 rgAD[wDrive-1].mdDensity = 1;
  1042.                 }
  1043.             break;
  1044.  
  1045.         case 'P':
  1046.         case 'W':
  1047.             /* write sector */
  1048.             Assert(wStat == 0x80, "write sector");
  1049.  
  1050.             if (rgAD[wDrive-1].fWP)     /* is drive write-protected? */
  1051.                 {
  1052.                 wRetStat = SIO_DEVDONE;
  1053.                 break;
  1054.                 }
  1055.  
  1056.             if ((wSector<0) || (wSector >=720))
  1057.                 {
  1058.                 wRetStat = SIO_NAK;
  1059.                 break;
  1060.                 }
  1061.  
  1062.             if (fDD)    /* assumes D1: */
  1063.                 {
  1064.                 Blitb(lMemory + (unsigned)(wBuff),
  1065.                      lrgbDrive + (long)(wSector)*256L, wBytes);
  1066.                 }
  1067.             else
  1068.                 {
  1069.                 Blitb(lMemory + (unsigned)(wBuff),
  1070.                      lrgbDrive + liDrive + (long)(wSector)*128L, wBytes);
  1071.                 }
  1072.  
  1073.             if (fFastIO)
  1074.                 break;
  1075.             {
  1076.             /* simulate the time delay between sectors */
  1077.             int delay, sav4, sav5;
  1078.             
  1079.             /* simulate the beep beep write sound */
  1080.             sav4 = rgbSound[4];
  1081.             sav5 = rgbSound[5];
  1082.             rgbSound[4] = 80;
  1083.             rgbSound[5] = 0x66;
  1084.  
  1085.             for (delay = 0; delay<4000; delay++)
  1086.                 ;
  1087.             rgbSound[4] = 0;
  1088.             rgbSound[5] = 0;
  1089.  
  1090.             for (delay = 0; delay<12000; delay++)
  1091.                 ;
  1092.  
  1093.             rgbSound[4] = sav4;
  1094.             rgbSound[5] = sav5;
  1095.             }
  1096.             break;
  1097.         
  1098.         case 'R':
  1099.             /* read sector */
  1100.             Assert(wStat == 0x40, "read sector");
  1101.             if ((wSector<0) || (wSector >=720))
  1102.                 {
  1103.                 wRetStat = SIO_NAK;
  1104.                 break;
  1105.                 }
  1106.  
  1107.             if (fDD)    /* assumes D1: */
  1108.                 {
  1109.                 Blitb(lrgbDrive + liDrive + (long)(wSector)*256L,
  1110.                       lMemory + (unsigned)(wBuff), wBytes);
  1111.                 }
  1112.             else
  1113.                 {
  1114.                 Blitb(lrgbDrive + liDrive + (long)(wSector)*128L,
  1115.                       lMemory + (unsigned)(wBuff), wBytes);
  1116.                 }
  1117.  
  1118.             if (fFastIO)
  1119.                 break;
  1120.                 
  1121.             {
  1122.             /* simulate the time delay between sectors */
  1123.             int delay, sav4, sav5;
  1124.             
  1125.             /* simulate the beep beep read sound */
  1126.             sav4 = rgbSound[4];
  1127.             sav5 = rgbSound[5];
  1128.             rgbSound[4] = 33;
  1129.             rgbSound[5] = 0xA8;
  1130.  
  1131.             for (delay = 0; delay<6000; delay++)
  1132.                 ;
  1133.             rgbSound[4] = 0;
  1134.             rgbSound[5] = 0;
  1135.  
  1136.             if (fDD)
  1137.                 for (delay = 0; delay<15000; delay++) ;
  1138.             else
  1139.                 for (delay = 0; delay<6000; delay++) ;
  1140.  
  1141.             rgbSound[4] = sav4;
  1142.             rgbSound[5] = sav5;
  1143.             }
  1144.             break;
  1145.             }
  1146.         }
  1147.         }
  1148.     /* return status */
  1149.     Poke (0x303, wRetStat);
  1150. #ifdef NDEBUG
  1151.     printf("Returning from SIO\n");
  1152. #endif
  1153.     }
  1154.  
  1155. /* this routine swaps the 14K of memory from $C000-$FFFF to simlate
  1156. ** XL memory handling
  1157. */
  1158.  
  1159. swap_XL()
  1160.     {
  1161.     register long *pchMem, *pchBuf, *pchMem0;
  1162.     register long ch;
  1163.     register unsigned int u, i;
  1164.     
  1165.     pchMem = (long *)(lMemory + (unsigned)0xC000);
  1166.     pchBuf = (long *)(lrgbXLRAM - 16384L);
  1167.  
  1168. asm
  1169.     {
  1170.     move.w  #1023,i      ; 1024 * 4 = 4096
  1171. l1:
  1172.     move.l  (pchMem),D0
  1173.     move.l  (pchBuf),(pchMem)+
  1174.     move.l  D0,(pchBuf)+
  1175.     dbf     i,l1
  1176.  
  1177.     lea     2048(pchMem),pchMem
  1178.     lea     2048(pchBuf),pchBuf
  1179.  
  1180.     move.w  #2559,i      ;  2560 * 4 = 10240
  1181. l2:
  1182.     move.l  (pchMem),D0
  1183.     move.l  (pchBuf),(pchMem)+
  1184.     move.l  D0,(pchBuf)+
  1185.     dbf     i,l2
  1186.     }
  1187.     }
  1188.  
  1189. Atari()
  1190.     {
  1191. asm {
  1192.  
  1193. ; handler for SIO
  1194. vecSIO:
  1195.     move.l  arPC,drEA
  1196.     cmpi.w  #0xC000,drEA
  1197.     bcs     vecCIO2         ; if PC < $C000, abort SIO
  1198.  
  1199.     SAVEREGS
  1200.     jsr     enter_SIO
  1201.     LOADREGS
  1202.  
  1203.     move.b  #0,drA          ; SIO clears A
  1204.     move.w  #0x303,drEA
  1205.     move.l  drEA,arEA
  1206.     move.b  (arEA),drY      ; Y = status
  1207.     move.b  drY,drST        ; set NZ flags
  1208.     ext.w   drST
  1209.     DISPATCH
  1210.  
  1211. vecCIO2:
  1212.     UNUSED
  1213.  
  1214.  
  1215. ; handler for ROM, do nothing
  1216. wsB00:
  1217.     addq.l  #2,SP
  1218.     DISPATCH
  1219.  
  1220. ; XL RAM handling ($C000-$FFFF)
  1221. wsB01:
  1222.     move.w  (SP)+,drDATA
  1223.  
  1224.     tst.b   fXLRAM      ; is ROM disabled
  1225.     beq.s   wsB01_x     ; no, so don't write
  1226.  
  1227.     move.l  drEA,arEA
  1228.     move.b  drDATA,(arEA)
  1229. wsB01_x:
  1230.     DISPATCH
  1231.  
  1232. wsB02:
  1233.     addq.l  #2,SP
  1234.     DISPATCH
  1235.  
  1236. wsB03:
  1237.     addq.l  #2,SP
  1238.     DISPATCH
  1239.  
  1240. ; player #1
  1241. wsB04:
  1242.     move.w  (SP)+,drDATA
  1243.     move.l  drEA,arEA
  1244.     cmp.b   (arEA),drDATA
  1245.     beq.s   wsB04_x
  1246.     move.b  drDATA,(arEA)
  1247.     st      fPMGRedraw
  1248. wsB04_x:
  1249.     DISPATCH
  1250.  
  1251. ; player #2
  1252. wsB05:
  1253.     move.w  (SP)+,drDATA
  1254.     move.l  drEA,arEA
  1255.     cmp.b   (arEA),drDATA
  1256.     beq.s   wsB05_x
  1257.     move.b  drDATA,(arEA)
  1258.     st      fPMGRedraw
  1259. wsB05_x:
  1260.     DISPATCH
  1261.  
  1262. ; player #3
  1263. wsB06:
  1264.     move.w  (SP)+,drDATA
  1265.     move.l  drEA,arEA
  1266.     cmp.b   (arEA),drDATA
  1267.     beq.s   wsB06_x
  1268.     move.b  drDATA,(arEA)
  1269.     st      fPMGRedraw
  1270. wsB06_x:
  1271.     DISPATCH
  1272.  
  1273. ; player #4
  1274. wsB07:
  1275.     move.w  (SP)+,drDATA
  1276.     move.l  drEA,arEA
  1277.     cmp.b   (arEA),drDATA
  1278.     beq.s   wsB07_x
  1279.     move.b  drDATA,(arEA)
  1280.     st      fPMGRedraw
  1281. wsB07_x:
  1282.     DISPATCH
  1283.  
  1284. wsB08:
  1285.     move.w  (SP)+,drDATA
  1286.     move.l  drEA,arEA
  1287.     cmp.b   (arEA),drDATA
  1288.     beq.s   wsB08_x
  1289.     move.b  drDATA,(arEA)
  1290.     st      fPMGRedraw
  1291. wsB08_x:
  1292.     DISPATCH
  1293.  
  1294. wsB09:
  1295.     addq.l  #2,SP
  1296.     DISPATCH
  1297. wsB0A:
  1298.     addq.l  #2,SP
  1299.     DISPATCH
  1300. wsB0B:
  1301.     addq.l  #2,SP
  1302.     DISPATCH
  1303.  
  1304. ; PIA chip
  1305.  
  1306. wsPIA00:
  1307.     addq.l  #2,SP
  1308.     DISPATCH
  1309.  
  1310. ; $D301 - XL PORT B or 400/800 joystick
  1311. wsPIA01:
  1312.     move.w  (SP)+,drDATA
  1313.     tst.w   fAtariXL
  1314.     beq     wsPIA01_x
  1315.     ori.w   #0x00FC,drEA
  1316.     move.l  drEA,arEA
  1317.     move.b  drDATA,(arEA)
  1318.     move.b  fXLRAM,drEA         ; get old value of ~b0
  1319.     btst    #0,drDATA           ; test bank select bit
  1320.     seq     fXLRAM              ; if b0==0, OS ROM disabled
  1321.     seq     drDATA
  1322.     cmp.b   drDATA,drEA
  1323.     beq.s   wsPIA01_x
  1324.     movem.l D0-D7/A0-A6,-(SP)
  1325.     jsr     swap_XL             ; go swap memory
  1326.     movem.l (SP)+,D0-D7/A0-A6
  1327.     nop
  1328. wsPIA01_x:
  1329.     DISPATCH
  1330.  
  1331. wsPIA02:
  1332.     addq.l  #2,SP
  1333.     DISPATCH
  1334.  
  1335. wsPIA03:
  1336.     addq.l  #2,SP
  1337.     DISPATCH
  1338.  
  1339. ; GTIA chip
  1340.  
  1341. wsGTIA00:
  1342.     move.w  (SP)+,drDATA
  1343.     ori.w   #0x00E0,drEA
  1344.     move.l  drEA,arEA
  1345.     cmp.b   (arEA),drDATA
  1346.     beq.s   wsGTIA00_x
  1347.     move.b  drDATA,(arEA)
  1348.     st      fPMGRedraw
  1349. wsGTIA00_x:
  1350.     DISPATCH
  1351.  
  1352. wsGTIA01:
  1353.     move.w  (SP)+,drDATA
  1354.     ori.w   #0x00E0,drEA
  1355.     move.l  drEA,arEA
  1356.     cmp.b   (arEA),drDATA
  1357.     beq.s   wsGTIA01_x
  1358.     move.b  drDATA,(arEA)
  1359.     st      fPMGRedraw
  1360. wsGTIA01_x:
  1361.     DISPATCH
  1362.  
  1363. wsGTIA02:
  1364.     move.w  (SP)+,drDATA
  1365.     ori.w   #0x00E0,drEA
  1366.     move.l  drEA,arEA
  1367.     cmp.b   (arEA),drDATA
  1368.     beq.s   wsGTIA02_x
  1369.     move.b  drDATA,(arEA)
  1370.     st      fPMGRedraw
  1371. wsGTIA02_x:
  1372.     DISPATCH
  1373.  
  1374. wsGTIA03:
  1375.     move.w  (SP)+,drDATA
  1376.     ori.w   #0x00E0,drEA
  1377.     move.l  drEA,arEA
  1378.     cmp.b   (arEA),drDATA
  1379.     beq.s   wsGTIA03_x
  1380.     move.b  drDATA,(arEA)
  1381.     st      fPMGRedraw
  1382. wsGTIA03_x:
  1383.     DISPATCH
  1384.  
  1385. wsGTIA04:
  1386.     move.w  (SP)+,drDATA
  1387.     ori.w   #0x00E0,drEA
  1388.     move.l  drEA,arEA
  1389.     cmp.b   (arEA),drDATA
  1390.     beq.s   wsGTIA04_x
  1391.     move.b  drDATA,(arEA)
  1392.     st      fPMGRedraw
  1393. wsGTIA04_x:
  1394.     DISPATCH
  1395.  
  1396. wsGTIA05:
  1397.     move.w  (SP)+,drDATA
  1398.     ori.w   #0x00E0,drEA
  1399.     move.l  drEA,arEA
  1400.     cmp.b   (arEA),drDATA
  1401.     beq.s   wsGTIA05_x
  1402.     move.b  drDATA,(arEA)
  1403.     st      fPMGRedraw
  1404. wsGTIA05_x:
  1405.     DISPATCH
  1406.  
  1407. wsGTIA06:
  1408.     move.w  (SP)+,drDATA
  1409.     ori.w   #0x00E0,drEA
  1410.     move.l  drEA,arEA
  1411.     cmp.b   (arEA),drDATA
  1412.     beq.s   wsGTIA06_x
  1413.     move.b  drDATA,(arEA)
  1414.     st      fPMGRedraw
  1415. wsGTIA06_x:
  1416.     DISPATCH
  1417.  
  1418. wsGTIA07:
  1419.     move.w  (SP)+,drDATA
  1420.     ori.w   #0x00E0,drEA
  1421.     move.l  drEA,arEA
  1422.     cmp.b   (arEA),drDATA
  1423.     beq.s   wsGTIA07_x
  1424.     move.b  drDATA,(arEA)
  1425.     st      fPMGRedraw
  1426. wsGTIA07_x:
  1427.     DISPATCH
  1428.  
  1429. wsGTIA08:
  1430.     move.w  (SP)+,drDATA
  1431.     ori.w   #0x00E0,drEA
  1432.     move.l  drEA,arEA
  1433.     cmp.b   (arEA),drDATA
  1434.     beq.s   wsGTIA08_x
  1435.     move.b  drDATA,(arEA)
  1436.     st      fPMGRedraw
  1437. wsGTIA08_x:
  1438.     DISPATCH
  1439.  
  1440. wsGTIA09:
  1441.     move.w  (SP)+,drDATA
  1442.     ori.w   #0x00E0,drEA
  1443.     move.l  drEA,arEA
  1444.     cmp.b   (arEA),drDATA
  1445.     beq.s   wsGTIA09_x
  1446.     move.b  drDATA,(arEA)
  1447.     st      fPMGRedraw
  1448. wsGTIA09_x:
  1449.     DISPATCH
  1450.  
  1451. wsGTIA0A:
  1452.     move.w  (SP)+,drDATA
  1453.     ori.w   #0x00E0,drEA
  1454.     move.l  drEA,arEA
  1455.     cmp.b   (arEA),drDATA
  1456.     beq.s   wsGTIA0A_x
  1457.     move.b  drDATA,(arEA)
  1458.     st      fPMGRedraw
  1459. wsGTIA0A_x:
  1460.     DISPATCH
  1461.  
  1462. wsGTIA0B:
  1463.     move.w  (SP)+,drDATA
  1464.     ori.w   #0x00E0,drEA
  1465.     move.l  drEA,arEA
  1466.     cmp.b   (arEA),drDATA
  1467.     beq.s   wsGTIA0B_x
  1468.     move.b  drDATA,(arEA)
  1469.     st      fPMGRedraw
  1470. wsGTIA0B_x:
  1471.     DISPATCH
  1472.  
  1473. wsGTIA0C:
  1474.     move.w  (SP)+,drDATA
  1475.     ori.w   #0x00E0,drEA
  1476.     move.l  drEA,arEA
  1477.     cmp.b   (arEA),drDATA
  1478.     beq.s   wsGTIA0C_x
  1479.     move.b  drDATA,(arEA)
  1480. wsGTIA0C_x:
  1481.     DISPATCH
  1482.  
  1483. wsGTIA0D:
  1484.     move.w  (SP)+,drDATA
  1485.     ori.w   #0x00E0,drEA
  1486.     move.l  drEA,arEA
  1487.     cmp.b   (arEA),drDATA
  1488.     beq.s   wsGTIA0D_x
  1489.     move.b  drDATA,(arEA)
  1490. wsGTIA0D_x:
  1491.     DISPATCH
  1492.  
  1493. wsGTIA0E:
  1494.     move.w  (SP)+,drDATA
  1495.     ori.w   #0x00E0,drEA
  1496.     move.l  drEA,arEA
  1497.     cmp.b   (arEA),drDATA
  1498.     beq.s   wsGTIA0E_x
  1499.     move.b  drDATA,(arEA)
  1500. wsGTIA0E_x:
  1501.     DISPATCH
  1502.  
  1503. wsGTIA0F:
  1504.     move.w  (SP)+,drDATA
  1505.     ori.w   #0x00E0,drEA
  1506.     move.l  drEA,arEA
  1507.     cmp.b   (arEA),drDATA
  1508.     beq.s   wsGTIA0F_x
  1509.     move.b  drDATA,(arEA)
  1510. wsGTIA0F_x:
  1511.     DISPATCH
  1512.  
  1513. wsGTIA10:
  1514.     move.w  (SP)+,drDATA
  1515.     ori.w   #0x00E0,drEA
  1516.     move.l  drEA,arEA
  1517.     cmp.b   (arEA),drDATA
  1518.     beq.s   wsGTIA10_x
  1519.     move.b  drDATA,(arEA)
  1520. wsGTIA10_x:
  1521.     DISPATCH
  1522.  
  1523. wsGTIA11:
  1524.     move.w  (SP)+,drDATA
  1525.     ori.w   #0x00E0,drEA
  1526.     move.l  drEA,arEA
  1527.     cmp.b   (arEA),drDATA
  1528.     beq.s   wsGTIA11_x
  1529.     move.b  drDATA,(arEA)
  1530. wsGTIA11_x:
  1531.     DISPATCH
  1532.  
  1533. wsGTIA12:
  1534.     move.w  (SP)+,drDATA
  1535.     ori.w   #0x00E0,drEA
  1536.     move.l  drEA,arEA
  1537.     cmp.b   (arEA),drDATA
  1538.     beq.s   wsGTIA12_x
  1539.     move.b  drDATA,(arEA)
  1540. wsGTIA12_x:
  1541.     DISPATCH
  1542.  
  1543. wsGTIA13:
  1544.     move.w  (SP)+,drDATA
  1545.     ori.w   #0x00E0,drEA
  1546.     move.l  drEA,arEA
  1547.     cmp.b   (arEA),drDATA
  1548.     beq.s   wsGTIA13_x
  1549.     move.b  drDATA,(arEA)
  1550. wsGTIA13_x:
  1551.     DISPATCH
  1552.  
  1553. wsGTIA14:
  1554.     move.w  (SP)+,drDATA
  1555.     ori.w   #0x00E0,drEA
  1556.     move.l  drEA,arEA
  1557.     cmp.b   (arEA),drDATA
  1558.     beq.s   wsGTIA14_x
  1559.     move.b  drDATA,(arEA)
  1560. wsGTIA14_x:
  1561.     DISPATCH
  1562.  
  1563. wsGTIA15:
  1564.     move.w  (SP)+,drDATA
  1565.     ori.w   #0x00E0,drEA
  1566.     move.l  drEA,arEA
  1567.     cmp.b   (arEA),drDATA
  1568.     beq.s   wsGTIA15_x
  1569.     move.b  drDATA,(arEA)
  1570. wsGTIA15_x:
  1571.     DISPATCH
  1572.  
  1573. ; $D016 - COLPF0 - playfield color 0
  1574. wsGTIA16:
  1575.     move.w  (SP)+,drDATA
  1576.     ori.w   #0x00E0,drEA
  1577.     move.l  drEA,arEA
  1578.     cmp.b   (arEA),drDATA
  1579.     beq.s   wsGTIA16_x
  1580.     move.b  drDATA,(arEA)
  1581.  
  1582.     tst.w   fIsMono
  1583.     bne.s   wsGTIA16_x
  1584.     lea     rgwRainbow,arEA
  1585.     andi.w  #0xFE,drDATA
  1586.     move.w  0(arEA,drDATA.w),drDATA
  1587.     move.w  drDATA,rgwAtColors+2
  1588.     move.w  drDATA,0x8242
  1589. wsGTIA16_x:
  1590.     DISPATCH
  1591.  
  1592. ; $D017 - COLPF1 - playfield color 1
  1593. wsGTIA17:
  1594.     move.w  (SP)+,drDATA
  1595.     ori.w   #0x00E0,drEA
  1596.     move.l  drEA,arEA
  1597.     cmp.b   (arEA),drDATA
  1598.     beq.s   wsGTIA17_x
  1599.     move.b  drDATA,(arEA)
  1600.  
  1601.     tst.w   fIsMono
  1602.     bne.s   wsGTIA17_x
  1603.     move.b  1(arEA),-(SP)       ; get background color
  1604.     lea     rgwRainbow,arEA
  1605.     andi.w  #0xFE,drDATA
  1606.     move.w  drDATA,drEA
  1607.     move.w  0(arEA,drDATA.w),drDATA
  1608.     move.w  drDATA,rgwAtColors+4
  1609.     move.w  drDATA,0x8244
  1610.     move.b  (SP)+,drDATA         ; get background color
  1611.     andi.w  #0x000E,drEA
  1612.     andi.w  #0x00F0,drDATA
  1613.     or.w    drEA,drDATA
  1614.     move.w  0(arEA,drDATA.w),drDATA
  1615.     move.w  drDATA,rgwAtColors+14
  1616.     move.w  drDATA,0x824E
  1617. wsGTIA17_x:
  1618.     DISPATCH
  1619.  
  1620. ; $D018 - COLPF2 - playfield color 2
  1621. wsGTIA18:
  1622.     move.w  (SP)+,drDATA
  1623.     ori.w   #0x00E0,drEA
  1624.     move.l  drEA,arEA
  1625.     cmp.b   (arEA),drDATA
  1626.     beq.s   wsGTIA18_x
  1627.     move.b  drDATA,(arEA)
  1628.  
  1629.     tst.w   fIsMono
  1630.     bne.s   wsGTIA18_x
  1631.     move.b  -1(arEA),-(SP)      ; get foreground color
  1632.     lea     rgwRainbow,arEA
  1633.     andi.w  #0xFE,drDATA
  1634.     move.w  drDATA,drEA
  1635.     move.w  0(arEA,drDATA.w),drDATA
  1636.     move.w  drDATA,rgwAtColors+6
  1637.     move.w  drDATA,0x8246
  1638.     move.b  (SP)+,drDATA         ; get foreground color
  1639.     andi.w  #0x00F0,drEA
  1640.     andi.w  #0x000E,drDATA
  1641.     or.w    drEA,drDATA
  1642.     move.w  0(arEA,drDATA.w),drDATA
  1643.     move.w  drDATA,rgwAtColors+14
  1644.     move.w  drDATA,0x824E
  1645. wsGTIA18_x:
  1646.     DISPATCH
  1647.  
  1648. ; $D019 - COLPF3 - playfield color 3
  1649. wsGTIA19:
  1650.     move.w  (SP)+,drDATA
  1651.     ori.w   #0x00E0,drEA
  1652.     move.l  drEA,arEA
  1653.     cmp.b   (arEA),drDATA
  1654.     beq.s   wsGTIA19_x
  1655.     move.b  drDATA,(arEA)
  1656.  
  1657.     tst.w   fIsMono
  1658.     bne.s   wsGTIA19_x
  1659.     lea     rgwRainbow,arEA
  1660.     andi.w  #0xFE,drDATA
  1661.     move.w  0(arEA,drDATA.w),drDATA
  1662.     move.w  drDATA,rgwAtColors+8
  1663.     move.w  drDATA,0x8248
  1664. wsGTIA19_x:
  1665.     DISPATCH
  1666.  
  1667. ; $D01A - COLBK - background color
  1668. wsGTIA1A:
  1669.     move.w  (SP)+,drDATA
  1670.     ori.w   #0x00E0,drEA
  1671.     move.l  drEA,arEA
  1672.     cmp.b   (arEA),drDATA
  1673.     beq.s   wsGTIA1A_x
  1674.     move.b  drDATA,(arEA)
  1675.  
  1676.     tst.w   fIsMono
  1677.     bne.s   wsGTIA1A_x
  1678.  
  1679.     lea     rgwRainbow,arEA
  1680.     andi.w  #0xFE,drDATA
  1681.     move.w  0(arEA,drDATA.w),drDATA
  1682.     move.w  drDATA,rgwAtColors+0
  1683.     move.w  drDATA,0x8240
  1684. wsGTIA1A_x:
  1685.     DISPATCH
  1686.  
  1687. wsGTIA1B:
  1688.     move.w  (SP)+,drDATA
  1689.     ori.w   #0x00E0,drEA
  1690.     move.l  drEA,arEA
  1691.     cmp.b   (arEA),drDATA
  1692.     beq.s   wsGTIA1B_x
  1693.     move.b  drDATA,(arEA)
  1694. wsGTIA1B_x:
  1695.     DISPATCH
  1696.  
  1697. wsGTIA1C:
  1698.     move.w  (SP)+,drDATA
  1699.     ori.w   #0x00E0,drEA
  1700.     move.l  drEA,arEA
  1701.     cmp.b   (arEA),drDATA
  1702.     beq.s   wsGTIA1C_x
  1703.     move.b  drDATA,(arEA)
  1704. wsGTIA1C_x:
  1705.     DISPATCH
  1706.  
  1707. ; $D01D - GRACTL
  1708. wsGTIA1D:
  1709.     move.w  (SP)+,drDATA
  1710.     ori.w   #0x00E0,drEA
  1711.     move.l  drEA,arEA
  1712.     cmp.b   (arEA),drDATA
  1713.     beq.s   wsGTIA1D_x
  1714.     move.b  drDATA,(arEA)
  1715.     st      fPMGRedraw
  1716. wsGTIA1D_x:
  1717.     DISPATCH
  1718.  
  1719. wsGTIA1E:
  1720.     move.w  (SP)+,drDATA
  1721.     ori.w   #0x00E0,drEA
  1722.     move.l  drEA,arEA
  1723.     cmp.b   (arEA),drDATA
  1724.     beq.s   wsGTIA1E_x
  1725.     move.b  drDATA,(arEA)
  1726. wsGTIA1E_x:
  1727.     DISPATCH
  1728.  
  1729. ; $D01F - speaker
  1730. wsGTIA1F:
  1731.     move.w  (SP)+,drDATA
  1732.     ori.w   #0x00E0,drEA
  1733.     move.l  drEA,arEA
  1734.     cmp.b   (arEA),drDATA
  1735.     beq.s   wsGTIA1F_x
  1736.     move.b  drDATA,(arEA)
  1737.  
  1738.     bra     wsGTIA1F_x      ; diasble keycicks for now ~~~
  1739.  
  1740.     lea     0x8800,arEA
  1741.     btst    #3,drDATA
  1742.     bne.s   wsGTIA1F0       ; bit on = speaker off
  1743.  
  1744.     move.b  #10,(arEA)
  1745.     move.b  #0x0F,(arEA)    ; set C volume = $F
  1746.     move.b  #7,(arEA)
  1747.     move.b  (arEA),drDATA
  1748.     andi.b  #0xDF,drDATA
  1749.     move.b  drDATA,2(arEA)   ; enable C noise
  1750. wsGTIA1F_x:
  1751.     DISPATCH
  1752.  
  1753. wsGTIA1F0:
  1754.     move.b  #10,(arEA)
  1755.     move.b  #0x00,(arEA)    ; set C volume = $0
  1756.     move.b  #7,(arEA)
  1757.     move.b  (arEA),drDATA
  1758.     ori.b   #0x24,drDATA
  1759.     move.b  drDATA,2(arEA)   ; disable C
  1760.     DISPATCH
  1761.  
  1762. ; POKEY chip
  1763.  
  1764. ; $D200-$D208 - sound registers, handled by VBI
  1765. wsPOK00:
  1766.     move.w  (SP)+,drDATA
  1767.     ori.w   #0x00F0,drEA
  1768.     move.l  drEA,arEA
  1769.     cmp.b   (arEA),drDATA
  1770.     beq.s   wsPOK00_x
  1771.     move.b  drDATA,(arEA)
  1772.     move.b  drDATA,rgbSound
  1773. wsPOK00_x:
  1774.     DISPATCH
  1775.  
  1776. wsPOK01:
  1777.     move.w  (SP)+,drDATA
  1778.     ori.w   #0x00F0,drEA
  1779.     move.l  drEA,arEA
  1780.     cmp.b   (arEA),drDATA
  1781.     beq.s   wsPOK01_x
  1782.     move.b  drDATA,(arEA)
  1783.     move.b  drDATA,rgbSound+1
  1784. wsPOK01_x:
  1785.     DISPATCH
  1786.  
  1787. wsPOK02:
  1788.     move.w  (SP)+,drDATA
  1789.     ori.w   #0x00F0,drEA
  1790.     move.l  drEA,arEA
  1791.     cmp.b   (arEA),drDATA
  1792.     beq.s   wsPOK02_x
  1793.     move.b  drDATA,(arEA)
  1794.     move.b  drDATA,rgbSound+2
  1795. wsPOK02_x:
  1796.     DISPATCH
  1797.  
  1798. wsPOK03:
  1799.     move.w  (SP)+,drDATA
  1800.     ori.w   #0x00F0,drEA
  1801.     move.l  drEA,arEA
  1802.     cmp.b   (arEA),drDATA
  1803.     beq.s   wsPOK03_x
  1804.     move.b  drDATA,(arEA)
  1805.     move.b  drDATA,rgbSound+3
  1806. wsPOK03_x:
  1807.     DISPATCH
  1808.  
  1809. wsPOK04:
  1810.     move.w  (SP)+,drDATA
  1811.     ori.w   #0x00F0,drEA
  1812.     move.l  drEA,arEA
  1813.     cmp.b   (arEA),drDATA
  1814.     beq.s   wsPOK04_x
  1815.     move.b  drDATA,(arEA)
  1816.     move.b  drDATA,rgbSound+4
  1817. wsPOK04_x:
  1818.     DISPATCH
  1819.  
  1820. wsPOK05:
  1821.     move.w  (SP)+,drDATA
  1822.     ori.w   #0x00F0,drEA
  1823.     move.l  drEA,arEA
  1824.     cmp.b   (arEA),drDATA
  1825.     beq.s   wsPOK05_x
  1826.     move.b  drDATA,(arEA)
  1827.     move.b  drDATA,rgbSound+5
  1828. wsPOK05_x:
  1829.     DISPATCH
  1830.  
  1831. wsPOK06:
  1832.     move.w  (SP)+,drDATA
  1833.     ori.w   #0x00F0,drEA
  1834.     move.l  drEA,arEA
  1835.     cmp.b   (arEA),drDATA
  1836.     beq.s   wsPOK06_x
  1837.     move.b  drDATA,(arEA)
  1838.     move.b  drDATA,rgbSound+6
  1839. wsPOK06_x:
  1840.     DISPATCH
  1841.  
  1842. wsPOK07:
  1843.     move.w  (SP)+,drDATA
  1844.     ori.w   #0x00F0,drEA
  1845.     move.l  drEA,arEA
  1846.     cmp.b   (arEA),drDATA
  1847.     beq.s   wsPOK07_x
  1848.     move.b  drDATA,(arEA)
  1849.     move.b  drDATA,rgbSound+7
  1850. wsPOK07_x:
  1851.     DISPATCH
  1852.  
  1853. wsPOK08:
  1854.     move.w  (SP)+,drDATA
  1855.     ori.w   #0x00F0,drEA
  1856.     move.l  drEA,arEA
  1857.     cmp.b   (arEA),drDATA
  1858.     beq.s   wsPOK08_x
  1859.     move.b  drDATA,(arEA)
  1860.     move.b  drDATA,rgbSound+8
  1861. wsPOK08_x:
  1862.     DISPATCH
  1863.  
  1864. ; $D209 - STIMER
  1865. wsPOK09:
  1866.     move.w  (SP)+,drDATA
  1867.     ori.w   #0x00F0,drEA
  1868.     move.l  drEA,arEA
  1869.     cmp.b   (arEA),drDATA
  1870.     beq.s   wsPOK09_x
  1871.     move.b  drDATA,(arEA)
  1872.     move.b  drDATA,rgbSound+8
  1873. wsPOK09_x:
  1874.     DISPATCH
  1875.  
  1876. ; $D20A - a write to this location sets bits 7, 6, 5 of serial/key status $D20F
  1877. ; for now, set all 6 unused bits, (bits 3 = shift key, bit 2 = any key)
  1878. wsPOK0A:
  1879.     addq.l  #2,SP
  1880.     andi.w  #0xFF0F,drEA
  1881.     move.l  drEA,arEA
  1882.     ori.b   #0xF3,5(arEA)
  1883.     DISPATCH
  1884.  
  1885. wsPOK0B:
  1886.     move.w  (SP)+,drDATA
  1887.     ori.w   #0x00F0,drEA
  1888.     move.l  drEA,arEA
  1889.     cmp.b   (arEA),drDATA
  1890.     beq.s   wsPOK0B_x
  1891.     move.b  drDATA,(arEA)
  1892. wsPOK0B_x:
  1893.     DISPATCH
  1894.  
  1895. wsPOK0C:
  1896.     move.w  (SP)+,drDATA
  1897.     ori.w   #0x00F0,drEA
  1898.     move.l  drEA,arEA
  1899.     cmp.b   (arEA),drDATA
  1900.     beq.s   wsPOK0C_x
  1901.     move.b  drDATA,(arEA)
  1902. wsPOK0C_x:
  1903.     DISPATCH
  1904.  
  1905. wsPOK0D:
  1906.     move.w  (SP)+,drDATA
  1907.     ori.w   #0x00F0,drEA
  1908.     move.l  drEA,arEA
  1909.     cmp.b   (arEA),drDATA
  1910.     beq.s   wsPOK0D_x
  1911.     move.b  drDATA,(arEA)
  1912. wsPOK0D_x:
  1913.     DISPATCH
  1914.  
  1915. ; $D20E - IRQ enable
  1916. wsPOK0E:
  1917.     move.w  (SP)+,drDATA
  1918.     move.b  drDATA,bIRQmask(arEMUL) ; store IRQ enable
  1919.     and.b   bIRQ(arEMUL),drDATA
  1920.     move.b  drDATA,bIRQ(arEMUL)     ; clear IRQ interrupts
  1921.     DISPATCH
  1922.  
  1923. wsPOK0F:
  1924.     move.w  (SP)+,drDATA
  1925.     ori.w   #0x00F0,drEA
  1926.     move.l  drEA,arEA
  1927.     cmp.b   (arEA),drDATA
  1928.     beq.s   wsPOK0F_x
  1929.     move.b  drDATA,(arEA)
  1930. wsPOK0F_x:
  1931.     DISPATCH
  1932.  
  1933. ; ANTIC chip
  1934.  
  1935. ; $D400 - DMACTL
  1936. ; bits 0 and 1 control playfield width
  1937. ; bit 5 = DMA control
  1938. ; if value == 0 then clear video display
  1939. wsANT00:
  1940.     move.w  (SP)+,drDATA
  1941.     ori.w   #0x00F0,drEA
  1942.     move.l  drEA,arEA
  1943.     cmp.b   (arEA),drDATA
  1944.     beq.s   wsANT00_x
  1945.     move.b  drDATA,(arEA)
  1946.     beq.s   wsANT00_clr
  1947.     btst    #5,drDATA
  1948.     sne     fAtDMA
  1949.     andi.w  #0x03,drDATA
  1950.     move.w  drDATA,mdAtWidth
  1951.     st      fRedraw
  1952. wsANT00_x:
  1953.     DISPATCH
  1954. wsANT00_clr:
  1955.     move.w  #5119,drDATA
  1956.     move.l  lScr,arEA
  1957. wsANT00_2:
  1958.     clr.l   (arEA)+
  1959.     clr.l   (arEA)+
  1960.     dbf     drDATA,wsANT00_2
  1961.     sf      fAtDMA
  1962.     clr.w   mdAtWidth
  1963.     DISPATCH
  1964.  
  1965. wsANT01:
  1966.     move.w  (SP)+,drDATA
  1967.     ori.w   #0x00F0,drEA
  1968.     move.l  drEA,arEA
  1969.     cmp.b   (arEA),drDATA
  1970.     beq.s   wsANT01_x
  1971.     move.b  drDATA,(arEA)
  1972. wsANT01_x:
  1973.     DISPATCH
  1974.  
  1975. ; $D402 - DL base address lo byte
  1976. wsANT02:
  1977.     move.w  (SP)+,drDATA
  1978.     ori.w   #0x00F0,drEA
  1979.     move.l  drEA,arEA
  1980.     cmp.b   (arEA),drDATA
  1981.     beq.s   wsANT02_x
  1982.     move.b  drDATA,(arEA)
  1983.     cmp.b   uDLStart+1,drDATA
  1984.     beq.s   wsANT02_x
  1985.     move.b  drDATA,uDLStart+1
  1986.     tst.b   uDLStart
  1987.     beq.s   wsANT02_x
  1988.     st      fRedraw
  1989. wsANT02_x:
  1990.     DISPATCH
  1991.     
  1992. ; $D403 - DL base address hi byte
  1993. wsANT03:
  1994.     move.w  (SP)+,drDATA
  1995.     ori.w   #0x00F0,drEA
  1996.     move.l  drEA,arEA
  1997.     cmp.b   (arEA),drDATA
  1998.     beq.s   wsANT03_x
  1999.     move.b  drDATA,(arEA)
  2000.     cmp.b   uDLStart,drDATA
  2001.     beq.s   wsANT03_x
  2002.     move.b  drDATA,uDLStart
  2003.     beq.s   wsANT03_x
  2004.     st      fRedraw
  2005. wsANT03_x:
  2006.     DISPATCH
  2007.     
  2008. wsANT04:
  2009.     move.w  (SP)+,drDATA
  2010.     ori.w   #0x00F0,drEA
  2011.     move.l  drEA,arEA
  2012.     cmp.b   (arEA),drDATA
  2013.     beq.s   wsANT04_x
  2014.     move.b  drDATA,(arEA)
  2015. wsANT04_x:
  2016.     DISPATCH
  2017.  
  2018. wsANT05:
  2019.     move.w  (SP)+,drDATA
  2020.     ori.w   #0x00F0,drEA
  2021.     move.l  drEA,arEA
  2022.     cmp.b   (arEA),drDATA
  2023.     beq.s   wsANT05_x
  2024.     move.b  drDATA,(arEA)
  2025. wsANT05_x:
  2026.     DISPATCH
  2027.  
  2028. wsANT06:
  2029.     move.w  (SP)+,drDATA
  2030.     ori.w   #0x00F0,drEA
  2031.     move.l  drEA,arEA
  2032.     cmp.b   (arEA),drDATA
  2033.     beq.s   wsANT06_x
  2034.     move.b  drDATA,(arEA)
  2035. wsANT06_x:
  2036.     DISPATCH
  2037.  
  2038. ; $D407 - PMBASE
  2039. wsANT07:
  2040.     move.w  (SP)+,drDATA
  2041.     ori.w   #0x00F0,drEA
  2042.     move.l  drEA,arEA
  2043.     cmp.b   (arEA),drDATA
  2044.     beq.s   wsANT07_x
  2045.     move.b  drDATA,(arEA)
  2046.     st      fPMGRedraw
  2047. wsANT07_x:
  2048.     DISPATCH
  2049.  
  2050. wsANT08:
  2051.     move.w  (SP)+,drDATA
  2052.     ori.w   #0x00F0,drEA
  2053.     move.l  drEA,arEA
  2054.     cmp.b   (arEA),drDATA
  2055.     beq.s   wsANT08_x
  2056.     move.b  drDATA,(arEA)
  2057. wsANT08_x:
  2058.     DISPATCH
  2059.  
  2060. ; $D409 - CHBASE
  2061. wsANT09:
  2062.     move.w  (SP)+,drDATA
  2063.     ori.w   #0x00F0,drEA
  2064.     move.l  drEA,arEA
  2065.     andi.w  #0xFE,drDATA
  2066.     cmp.b   (arEA),drDATA
  2067.     beq.s   wsANT09_x
  2068.     move.b  drDATA,(arEA)
  2069.     cmp.b   uAtCharBase,drDATA
  2070.     beq.s   wsANT09_x
  2071.     move.b  drDATA,uAtCharBase
  2072.     st      fRedraw
  2073. wsANT09_x:
  2074.     DISPATCH
  2075.  
  2076. ; $D40A - WSYNC
  2077. wsANT0A:
  2078.     addq.l  #2,SP
  2079.     muls    D0,D0
  2080.     muls    D0,D0
  2081.     muls    D0,D0
  2082.     DISPATCH
  2083.  
  2084. wsANT0B:
  2085.     move.w  (SP)+,drDATA
  2086.     ori.w   #0x00F0,drEA
  2087.     move.l  drEA,arEA
  2088.     cmp.b   (arEA),drDATA
  2089.     beq.s   wsANT0B_x
  2090.     move.b  drDATA,(arEA)
  2091. wsANT0B_x:
  2092.     DISPATCH
  2093.     
  2094. wsANT0C:
  2095.     move.w  (SP)+,drDATA
  2096.     ori.w   #0x00F0,drEA
  2097.     move.l  drEA,arEA
  2098.     cmp.b   (arEA),drDATA
  2099.     beq.s   wsANT0C_x
  2100.     move.b  drDATA,(arEA)
  2101. wsANT0C_x:
  2102.     DISPATCH
  2103.  
  2104. wsANT0D:
  2105.     move.w  (SP)+,drDATA
  2106.     ori.w   #0x00F0,drEA
  2107.     move.l  drEA,arEA
  2108.     cmp.b   (arEA),drDATA
  2109.     beq.s   wsANT0D_x
  2110.     move.b  drDATA,(arEA)
  2111. wsANT0D_x:
  2112.     DISPATCH
  2113.  
  2114. ; $D40E - NMI enable
  2115. wsANT0E:
  2116.     move.w  (SP)+,drDATA
  2117.     ori.w   #0x00F0,drEA
  2118.     move.l  drEA,arEA
  2119.     cmp.b   (arEA),drDATA
  2120.     beq.s   wsANT0E_x
  2121.     andi.w  #0xC0,drDATA    ; only bits 6 and 7 used
  2122.     move.b  drDATA,(arEA)   ; 
  2123. wsANT0E_x:
  2124.     DISPATCH
  2125.  
  2126. wsANT0F:
  2127.     clr.b   bNMI(arEMUL)    ; clear NMIST
  2128.     addq.l  #2,SP
  2129.     DISPATCH
  2130.  
  2131. ; DL list routines
  2132. ; 0 - unused
  2133. ; 1 - DL byte, when modified, sets  fRedraw flag
  2134. ; 2..$F - ANTIC mode emulation
  2135.  
  2136. wsDL0:
  2137.     addq.l  #2,SP
  2138.     DISPATCH
  2139.  
  2140. ; handler for display list
  2141. wsDL1:
  2142.     move.w  (SP)+,drDATA
  2143.     move.l  drEA,arEA
  2144.     cmp.b   (arEA),drDATA
  2145.     beq.s   wsDL1_2
  2146.     st      fRedraw
  2147.     move.b  drDATA,(arEA)
  2148. wsDL1_2:
  2149.     DISPATCH
  2150.  
  2151. ; handler for ANTIC mode 2
  2152. wsDL2:
  2153.     move.w  (SP)+,drDATA
  2154.     movem.l D0-D7/A0-A6,-(SP)
  2155.     move.l  drEA,arEA           
  2156.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2157.     beq     wsDL2_exit          ; if same, just exit
  2158.  
  2159.     move.b  drDATA,(arEA)       ; store new byte to memory
  2160.     tst.w   fRedraw             ; if redraw flag, exit
  2161.     bne     wsDL2_exit
  2162.  
  2163.     move.w  #1,-(SP)            ; count of characters
  2164.     move.l  arEA,-(SP)          ; pointer character to plot
  2165.  
  2166.     lea     rgDL2,arEA          ; get start of DL structure
  2167. lNext2_1:
  2168.     move.l  (arEA)+,drDATA      ; get start[31:16] and ending[15:0] address 
  2169.     cmp.w   drDATA,drEA         ; is EA < end
  2170.     bcc     lNext2_2            ; no, next
  2171.  
  2172.     swap    drDATA              ; get start
  2173.     cmp.w   drDATA,drEA         ; is EA >= start
  2174.     bcs     lNext2_2            ; no, next
  2175.  
  2176.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2177.     move.w  drEA,-(SP)
  2178.     move.w  (arEA),-(SP)        ; get scan line offset
  2179.     jsr     plot_2              ; go plot a text character
  2180.     lea     10(SP),SP
  2181.     bra     wsDL2_exit
  2182.  
  2183. lNext2_2:
  2184.     move.w  (arEA)+,drDATA
  2185.     bpl     lNext2_1            ; next, if not end of list
  2186.     addq.l  #6,SP
  2187.  
  2188. wsDL2_exit:
  2189.     movem.l (SP)+,D0-D7/A0-A6
  2190.     DISPATCH
  2191.  
  2192. ; handler for ANTIC mode 3
  2193. wsDL3:
  2194.     move.w  (SP)+,drDATA
  2195.     movem.l D0-D7/A0-A6,-(SP)
  2196.     move.l  drEA,arEA           
  2197.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2198.     beq     wsDL3_exit          ; if same, just exit
  2199.  
  2200.     move.b  drDATA,(arEA)       ; store new byte to memory
  2201.     tst.w   fRedraw             ; if redraw flag, exit
  2202.     bne     wsDL3_exit
  2203.  
  2204.     move.w  #1,-(SP)            ; count of characters
  2205.     move.l  arEA,-(SP)          ; pointer character to plot
  2206.  
  2207.     lea     rgDL3,arEA          ; get start of DL structure
  2208. lNext3_1:
  2209.     move.l  (arEA)+,drDATA      ; get start[31:16] and ending[15:0] address 
  2210.     cmp.w   drDATA,drEA         ; is EA < end
  2211.     bcc     lNext3_2            ; no, next
  2212.  
  2213.     swap    drDATA              ; get start
  2214.     cmp.w   drDATA,drEA         ; is EA >= start
  2215.     bcs     lNext3_2            ; no, next
  2216.  
  2217.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2218.     move.w  drEA,-(SP)
  2219.     move.w  (arEA),-(SP)        ; get scan line offset
  2220.     jsr     plot_3              ; go plot a text character
  2221.     lea     10(SP),SP
  2222.     bra     wsDL3_exit
  2223.  
  2224. lNext3_2:
  2225.     move.w  (arEA)+,drDATA
  2226.     bpl     lNext3_1            ; next, if not end of list
  2227.     addq.l  #6,SP
  2228.  
  2229. wsDL3_exit:
  2230.     movem.l (SP)+,D0-D7/A0-A6
  2231.     DISPATCH
  2232.  
  2233. ; handler for ANTIC mode 4
  2234. wsDL4:
  2235.     move.w  (SP)+,drDATA
  2236.     movem.l D0-D7/A0-A6,-(SP)
  2237.     move.l  drEA,arEA           
  2238.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2239.     beq     wsDL4_exit          ; if same, just exit
  2240.  
  2241.     move.b  drDATA,(arEA)       ; store new byte to memory
  2242.     tst.w   fRedraw             ; if redraw flag, exit
  2243.     bne     wsDL4_exit
  2244.  
  2245.     move.w  #1,-(SP)            ; count of characters
  2246.     move.l  arEA,-(SP)          ; pointer character to plot
  2247.  
  2248.     lea     rgDL4,arEA          ; get start of DL structure
  2249. lNext4_1:
  2250.     move.l  (arEA)+,drDATA      ; get start[41:16] and ending[15:0] address 
  2251.     cmp.w   drDATA,drEA         ; is EA < end
  2252.     bcc     lNext4_2            ; no, next
  2253.  
  2254.     swap    drDATA              ; get start
  2255.     cmp.w   drDATA,drEA         ; is EA >= start
  2256.     bcs     lNext4_2            ; no, next
  2257.  
  2258.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2259.     move.w  drEA,-(SP)
  2260.     move.w  (arEA),-(SP)        ; get scan line offset
  2261.     jsr     plot_4              ; go plot a text character
  2262.     lea     10(SP),SP
  2263.     bra     wsDL4_exit
  2264.  
  2265. lNext4_2:
  2266.     move.w  (arEA)+,drDATA
  2267.     bpl     lNext4_1            ; next, if not end of list
  2268.     addq.l  #6,SP
  2269.  
  2270. wsDL4_exit:
  2271.     movem.l (SP)+,D0-D7/A0-A6
  2272.     DISPATCH
  2273.  
  2274. ; handler for ANTIC mode 5
  2275. wsDL5:
  2276.     move.w  (SP)+,drDATA
  2277.     movem.l D0-D7/A0-A6,-(SP)
  2278.     move.l  drEA,arEA           
  2279.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2280.     beq     wsDL5_exit          ; if same, just exit
  2281.  
  2282.     move.b  drDATA,(arEA)       ; store new byte to memory
  2283.     tst.w   fRedraw             ; if redraw flag, exit
  2284.     bne     wsDL5_exit
  2285.  
  2286.     move.w  #1,-(SP)            ; count of characters
  2287.     move.l  arEA,-(SP)          ; pointer character to plot
  2288.  
  2289.     lea     rgDL5,arEA          ; get start of DL structure
  2290. lNext5_1:
  2291.     move.l  (arEA)+,drDATA      ; get start[51:16] and ending[15:0] address 
  2292.     cmp.w   drDATA,drEA         ; is EA < end
  2293.     bcc     lNext5_2            ; no, next
  2294.  
  2295.     swap    drDATA              ; get start
  2296.     cmp.w   drDATA,drEA         ; is EA >= start
  2297.     bcs     lNext5_2            ; no, next
  2298.  
  2299.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2300.     move.w  drEA,-(SP)
  2301.     move.w  (arEA),-(SP)        ; get scan line offset
  2302.     jsr     plot_5              ; go plot a text character
  2303.     lea     10(SP),SP
  2304.     bra     wsDL5_exit
  2305.  
  2306. lNext5_2:
  2307.     move.w  (arEA)+,drDATA
  2308.     bpl     lNext5_1            ; next, if not end of list
  2309.     addq.l  #6,SP
  2310.  
  2311. wsDL5_exit:
  2312.     movem.l (SP)+,D0-D7/A0-A6
  2313.     DISPATCH
  2314.  
  2315. ; handler for ANTIC mode 6
  2316. wsDL6:
  2317.     move.w  (SP)+,drDATA
  2318.     movem.l D0-D7/A0-A6,-(SP)
  2319.     move.l  drEA,arEA           
  2320.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2321.     beq     wsDL6_exit          ; if same, just exit
  2322.  
  2323.     move.b  drDATA,(arEA)       ; store new byte to memory
  2324.     tst.w   fRedraw             ; if redraw flag, exit
  2325.     bne     wsDL6_exit
  2326.  
  2327.     move.w  #1,-(SP)            ; count of characters
  2328.     move.l  arEA,-(SP)          ; pointer character to plot
  2329.  
  2330.     lea     rgDL6,arEA          ; get start of DL structure
  2331. lNext6_1:
  2332.     move.l  (arEA)+,drDATA      ; get start[61:16] and ending[15:0] address 
  2333.     cmp.w   drDATA,drEA         ; is EA < end
  2334.     bcc     lNext6_2            ; no, next
  2335.  
  2336.     swap    drDATA              ; get start
  2337.     cmp.w   drDATA,drEA         ; is EA >= start
  2338.     bcs     lNext6_2            ; no, next
  2339.  
  2340.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2341.     move.w  drEA,-(SP)
  2342.     move.w  (arEA),-(SP)        ; get scan line offset
  2343.     jsr     plot_6              ; go plot a text character
  2344.     lea     10(SP),SP
  2345.     bra     wsDL6_exit
  2346.  
  2347. lNext6_2:
  2348.     move.w  (arEA)+,drDATA
  2349.     bpl     lNext6_1            ; next, if not end of list
  2350.     addq.l  #6,SP
  2351.  
  2352. wsDL6_exit:
  2353.     movem.l (SP)+,D0-D7/A0-A6
  2354.     DISPATCH
  2355.  
  2356. ; handler for ANTIC mode 7
  2357. wsDL7:
  2358.     move.w  (SP)+,drDATA
  2359.     movem.l D0-D7/A0-A6,-(SP)
  2360.     move.l  drEA,arEA           
  2361.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2362.     beq     wsDL7_exit          ; if same, just exit
  2363.  
  2364.     move.b  drDATA,(arEA)       ; store new byte to memory
  2365.     tst.w   fRedraw             ; if redraw flag, exit
  2366.     bne     wsDL7_exit
  2367.  
  2368.     move.w  #1,-(SP)            ; count of characters
  2369.     move.l  arEA,-(SP)          ; pointer character to plot
  2370.  
  2371.     lea     rgDL7,arEA          ; get start of DL structure
  2372. lNext7_1:
  2373.     move.l  (arEA)+,drDATA      ; get start[71:16] and ending[15:0] address 
  2374.     cmp.w   drDATA,drEA         ; is EA < end
  2375.     bcc     lNext7_2            ; no, next
  2376.  
  2377.     swap    drDATA              ; get start
  2378.     cmp.w   drDATA,drEA         ; is EA >= start
  2379.     bcs     lNext7_2            ; no, next
  2380.  
  2381.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2382.     move.w  drEA,-(SP)
  2383.     move.w  (arEA),-(SP)        ; get scan line offset
  2384.     jsr     plot_7              ; go plot a text character
  2385.     lea     10(SP),SP
  2386.     bra     wsDL7_exit
  2387.  
  2388. lNext7_2:
  2389.     move.w  (arEA)+,drDATA
  2390.     bpl     lNext7_1            ; next, if not end of list
  2391.     addq.l  #6,SP
  2392.  
  2393. wsDL7_exit:
  2394.     movem.l (SP)+,D0-D7/A0-A6
  2395.     DISPATCH
  2396.  
  2397. ; handler for ANTIC mode 8
  2398. wsDL8:
  2399.     move.w  (SP)+,drDATA
  2400.     movem.l D0-D7/A0-A6,-(SP)
  2401.     move.l  drEA,arEA           
  2402.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2403.     beq     wsDL8_exit          ; if same, just exit
  2404.  
  2405.     move.b  drDATA,(arEA)       ; store new byte to memory
  2406.     tst.w   fRedraw             ; if redraw flag, exit
  2407.     bne     wsDL8_exit
  2408.  
  2409.     move.w  #1,-(SP)            ; count of characters
  2410.     move.l  arEA,-(SP)          ; pointer character to plot
  2411.  
  2412.     lea     rgDL8,arEA          ; get start of DL structure
  2413. lNext8_1:
  2414.     move.l  (arEA)+,drDATA      ; get start[81:16] and ending[15:0] address 
  2415.     cmp.w   drDATA,drEA         ; is EA < end
  2416.     bcc     lNext8_2            ; no, next
  2417.  
  2418.     swap    drDATA              ; get start
  2419.     cmp.w   drDATA,drEA         ; is EA >= start
  2420.     bcs     lNext8_2            ; no, next
  2421.  
  2422.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2423.     move.w  drEA,-(SP)
  2424.     move.w  (arEA),-(SP)        ; get scan line offset
  2425.     jsr     plot_8              ; go plot a text character
  2426.     lea     10(SP),SP
  2427.     bra     wsDL8_exit
  2428.  
  2429. lNext8_2:
  2430.     move.w  (arEA)+,drDATA
  2431.     bpl     lNext8_1            ; next, if not end of list
  2432.     addq.l  #6,SP
  2433.  
  2434. wsDL8_exit:
  2435.     movem.l (SP)+,D0-D7/A0-A6
  2436.     DISPATCH
  2437.  
  2438. ; handler for ANTIC mode 9
  2439. wsDL9:
  2440.     move.w  (SP)+,drDATA
  2441.     movem.l D0-D7/A0-A6,-(SP)
  2442.     move.l  drEA,arEA           
  2443.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2444.     beq     wsDL9_exit          ; if same, just exit
  2445.  
  2446.     move.b  drDATA,(arEA)       ; store new byte to memory
  2447.     tst.w   fRedraw             ; if redraw flag, exit
  2448.     bne     wsDL9_exit
  2449.  
  2450.     move.w  #1,-(SP)            ; count of characters
  2451.     move.l  arEA,-(SP)          ; pointer character to plot
  2452.  
  2453.     lea     rgDL9,arEA          ; get start of DL structure
  2454. lNext9_1:
  2455.     move.l  (arEA)+,drDATA      ; get start[91:16] and ending[15:0] address 
  2456.     cmp.w   drDATA,drEA         ; is EA < end
  2457.     bcc     lNext9_2            ; no, next
  2458.  
  2459.     swap    drDATA              ; get start
  2460.     cmp.w   drDATA,drEA         ; is EA >= start
  2461.     bcs     lNext9_2            ; no, next
  2462.  
  2463.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2464.     move.w  drEA,-(SP)
  2465.     move.w  (arEA),-(SP)        ; get scan line offset
  2466.     jsr     plot_9              ; go plot a text character
  2467.     lea     10(SP),SP
  2468.     bra     wsDL9_exit
  2469.  
  2470. lNext9_2:
  2471.     move.w  (arEA)+,drDATA
  2472.     bpl     lNext9_1            ; next, if not end of list
  2473.     addq.l  #6,SP
  2474.  
  2475. wsDL9_exit:
  2476.     movem.l (SP)+,D0-D7/A0-A6
  2477.     DISPATCH
  2478.  
  2479. ; handler for ANTIC mode A
  2480. wsDLA:
  2481.     move.w  (SP)+,drDATA
  2482.     movem.l D0-D7/A0-A6,-(SP)
  2483.     move.l  drEA,arEA           
  2484.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2485.     beq     wsDLA_exit          ; if same, just exit
  2486.  
  2487.     move.b  drDATA,(arEA)       ; store new byte to memory
  2488.     tst.w   fRedraw             ; if redraw flag, exit
  2489.     bne     wsDLA_exit
  2490.  
  2491.     move.w  #1,-(SP)            ; count of characters
  2492.     move.l  arEA,-(SP)          ; pointer character to plot
  2493.  
  2494.     lea     rgDLA,arEA          ; get start of DL structure
  2495. lNextA_1:
  2496.     move.l  (arEA)+,drDATA      ; get start[A1:16] and ending[15:0] address 
  2497.     cmp.w   drDATA,drEA         ; is EA < end
  2498.     bcc     lNextA_2            ; no, next
  2499.  
  2500.     swap    drDATA              ; get start
  2501.     cmp.w   drDATA,drEA         ; is EA >= start
  2502.     bcs     lNextA_2            ; no, next
  2503.  
  2504.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2505.     move.w  drEA,-(SP)
  2506.     move.w  (arEA),-(SP)        ; get scan line offset
  2507.     jsr     plot_A              ; go plot a text character
  2508.     lea     10(SP),SP
  2509.     bra     wsDLA_exit
  2510.  
  2511. lNextA_2:
  2512.     move.w  (arEA)+,drDATA
  2513.     bpl     lNextA_1            ; next, if not end of list
  2514.     addq.l  #6,SP
  2515.  
  2516. wsDLA_exit:
  2517.     movem.l (SP)+,D0-D7/A0-A6
  2518.     DISPATCH
  2519.  
  2520. ; handler for ANTIC mode B
  2521. wsDLB:
  2522.     move.w  (SP)+,drDATA
  2523.     movem.l D0-D7/A0-A6,-(SP)
  2524.     move.l  drEA,arEA           
  2525.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2526.     beq     wsDLB_exit          ; if same, just exit
  2527.  
  2528.     move.b  drDATA,(arEA)       ; store new byte to memory
  2529.     tst.w   fRedraw             ; if redraw flag, exit
  2530.     bne     wsDLB_exit
  2531.  
  2532.     move.w  #1,-(SP)            ; count of characters
  2533.     move.l  arEA,-(SP)          ; pointer character to plot
  2534.  
  2535.     lea     rgDLB,arEA          ; get start of DL structure
  2536. lNextB_1:
  2537.     move.l  (arEA)+,drDATA      ; get start[B1:16] and ending[15:0] address 
  2538.     cmp.w   drDATA,drEA         ; is EA < end
  2539.     bcc     lNextB_2            ; no, next
  2540.  
  2541.     swap    drDATA              ; get start
  2542.     cmp.w   drDATA,drEA         ; is EA >= start
  2543.     bcs     lNextB_2            ; no, next
  2544.  
  2545.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2546.     move.w  drEA,-(SP)
  2547.     move.w  (arEA),-(SP)        ; get scan line offset
  2548.     jsr     plot_B              ; go plot a text character
  2549.     lea     10(SP),SP
  2550.     bra     wsDLB_exit
  2551.  
  2552. lNextB_2:
  2553.     move.w  (arEA)+,drDATA
  2554.     bpl     lNextB_1            ; next, if not end of list
  2555.     addq.l  #6,SP
  2556.  
  2557. wsDLB_exit:
  2558.     movem.l (SP)+,D0-D7/A0-A6
  2559.     DISPATCH
  2560.  
  2561. ; handler for ANTIC mode C
  2562. wsDLC:
  2563.     move.w  (SP)+,drDATA
  2564.     movem.l D0-D7/A0-A6,-(SP)
  2565.     move.l  drEA,arEA           
  2566.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2567.     beq     wsDLC_exit          ; if same, just exit
  2568.  
  2569.     move.b  drDATA,(arEA)       ; store new byte to memory
  2570.     tst.w   fRedraw             ; if redraw flag, exit
  2571.     bne     wsDLC_exit
  2572.  
  2573.     move.w  #1,-(SP)            ; count of characters
  2574.     move.l  arEA,-(SP)          ; pointer character to plot
  2575.  
  2576.     lea     rgDLC,arEA          ; get start of DL structure
  2577. lNextC_1:
  2578.     move.l  (arEA)+,drDATA      ; get start[C1:16] and ending[15:0] address 
  2579.     cmp.w   drDATA,drEA         ; is EA < end
  2580.     bcc     lNextC_2            ; no, next
  2581.  
  2582.     swap    drDATA              ; get start
  2583.     cmp.w   drDATA,drEA         ; is EA >= start
  2584.     bcs     lNextC_2            ; no, next
  2585.  
  2586.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2587.     move.w  drEA,-(SP)
  2588.     move.w  (arEA),-(SP)        ; get scan line offset
  2589.     jsr     plot_C              ; go plot a text character
  2590.     lea     10(SP),SP
  2591.     bra     wsDLC_exit
  2592.  
  2593. lNextC_2:
  2594.     move.w  (arEA)+,drDATA
  2595.     bpl     lNextC_1            ; next, if not end of list
  2596.     addq.l  #6,SP
  2597.  
  2598. wsDLC_exit:
  2599.     movem.l (SP)+,D0-D7/A0-A6
  2600.     DISPATCH
  2601.  
  2602. ; handler for ANTIC mode D
  2603. wsDLD:
  2604.     move.w  (SP)+,drDATA
  2605.     movem.l D0-D7/A0-A6,-(SP)
  2606.     move.l  drEA,arEA           
  2607.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2608.     beq     wsDLD_exit          ; if same, just exit
  2609.  
  2610.     move.b  drDATA,(arEA)       ; store new byte to memory
  2611.     tst.w   fRedraw             ; if redraw flag, exit
  2612.     bne     wsDLD_exit
  2613.  
  2614.     move.w  #1,-(SP)            ; count of characters
  2615.     move.l  arEA,-(SP)          ; pointer to character to plot
  2616.  
  2617.     lea     rgDLD,arEA          ; get start of DL structure
  2618. lNextD_1:
  2619.     move.l  (arEA)+,drDATA      ; get start[31:16] and ending[15:0] address 
  2620.     cmp.w   drDATA,drEA         ; is EA < end
  2621.     bcc     lNextD_2            ; no, next
  2622.  
  2623.     swap    drDATA              ; get start
  2624.     cmp.w   drDATA,drEA         ; is EA >= start
  2625.     bcs     lNextD_2            ; no, next
  2626.  
  2627.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2628.     move.w  drEA,-(SP)
  2629.     move.w  (arEA),-(SP)        ; get scan line offset
  2630.     jsr     plot_D              ; go plot a graphics byte
  2631.     lea     10(SP),SP
  2632.     bra     wsDLD_exit
  2633.  
  2634. lNextD_2:
  2635.     move.w  (arEA)+,drDATA
  2636.     bpl     lNextD_1            ; next, if not end of list
  2637.     addq.l  #6,SP
  2638.     
  2639. wsDLD_exit:
  2640.     movem.l (SP)+,D0-D7/A0-A6
  2641.     DISPATCH
  2642.  
  2643. ; handler for ANTIC mode E
  2644. wsDLE:
  2645.     move.w  (SP)+,drDATA
  2646.     movem.l D0-D7/A0-A6,-(SP)
  2647.     move.l  drEA,arEA           
  2648.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2649.     beq     wsDLE_exit          ; if same, just exit
  2650.  
  2651.     move.b  drDATA,(arEA)       ; store new byte to memory
  2652.     tst.w   fRedraw             ; if redraw flag, exit
  2653.     bne     wsDLE_exit
  2654.  
  2655.     move.w  #1,-(SP)            ; count of characters
  2656.     move.l  arEA,-(SP)          ; pointer to character to plot
  2657.  
  2658.     lea     rgDLE,arEA          ; get start of DL structure
  2659. lNextE_1:
  2660.     move.l  (arEA)+,drDATA      ; get start[31:16] and ending[15:0] address 
  2661.     cmp.w   drDATA,drEA         ; is EA < end
  2662.     bcc     lNextE_2            ; no, next
  2663.  
  2664.     swap    drDATA              ; get start
  2665.     cmp.w   drDATA,drEA         ; is EA >= start
  2666.     bcs     lNextE_2            ; no, next
  2667.  
  2668.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2669.     move.w  drEA,-(SP)
  2670.     move.w  (arEA),-(SP)        ; get scan line offset
  2671.     jsr     plot_E              ; go plot a graphics byte
  2672.     lea     10(SP),SP
  2673.     bra     wsDLE_exit
  2674.  
  2675. lNextE_2:
  2676.     move.w  (arEA)+,drDATA
  2677.     bpl     lNextE_1            ; next, if not end of list
  2678.     addq.l  #6,SP
  2679.     
  2680. wsDLE_exit:
  2681.     movem.l (SP)+,D0-D7/A0-A6
  2682.     DISPATCH
  2683.  
  2684. ; handler for ANTIC mode F
  2685. wsDLF:
  2686.     move.w  (SP)+,drDATA
  2687.     movem.l D0-D7/A0-A6,-(SP)
  2688.     move.l  drEA,arEA           
  2689.     cmp.b   (arEA),drDATA       ; compare with byte in memory
  2690.     beq     wsDLF_exit          ; if same, just exit
  2691.  
  2692.     move.b  drDATA,(arEA)       ; store new byte to memory
  2693.     tst.w   fRedraw             ; if redraw flag, exit
  2694.     bne     wsDLF_exit
  2695.  
  2696.     move.w  #1,-(SP)            ; count of characters
  2697.     move.l  arEA,-(SP)          ; pointer to character to plot
  2698.  
  2699.     lea     rgDLF,arEA          ; get start of DL structure
  2700. lNextF_1:
  2701.     move.l  (arEA)+,drDATA      ; get start[31:16] and ending[15:0] address 
  2702.     cmp.w   drDATA,drEA         ; is EA < end
  2703.     bcc     lNextF_2            ; no, next
  2704.  
  2705.     swap    drDATA              ; get start
  2706.     cmp.w   drDATA,drEA         ; is EA >= start
  2707.     bcs     lNextF_2            ; no, next
  2708.  
  2709.     sub.w   drDATA,drEA         ; convert EA to (0-999)
  2710.     move.w  drEA,-(SP)
  2711.     move.w  (arEA),-(SP)        ; get scan line offset
  2712.     jsr     plot_F              ; go plot a graphics byte
  2713.     lea     10(SP),SP
  2714.     bra     wsDLF_exit
  2715.  
  2716. lNextF_2:
  2717.     move.w  (arEA)+,drDATA
  2718.     bpl     lNextF_1            ; next, if not end of list
  2719.     addq.l  #6,SP
  2720.     
  2721. wsDLF_exit:
  2722.     movem.l (SP)+,D0-D7/A0-A6
  2723.     DISPATCH
  2724.  
  2725. wsBXX:
  2726.     addq.l  #2,SP
  2727.     DISPATCH
  2728.  
  2729. ; read service routines
  2730.  
  2731. rsB00:
  2732.     rts
  2733.  
  2734. ; XL RAM handling ($C000-$FFFF)
  2735. rsB01:
  2736.     rts
  2737.  
  2738. rsB02:
  2739.     rts
  2740. rsB03:
  2741.     rts
  2742. rsB04:
  2743.     rts
  2744. rsB05:
  2745.     rts
  2746. rsB06:
  2747.     rts
  2748. rsB07:
  2749.     rts
  2750. rsB08:
  2751.     rts
  2752. rsB09:
  2753.     rts
  2754. rsB0A:
  2755.     rts
  2756. rsB0B:
  2757.     rts
  2758.  
  2759. rsPIA00:
  2760.     ; joystick stuff
  2761.     move.l  drEA,arEA
  2762.     move.w  Joy0,drDATA
  2763.     move.w  drDATA,drEA
  2764.     lsl.w   #4,drEA
  2765.     lsr.w   #8,drDATA
  2766.     andi.w  #0x00F0,drEA
  2767.     andi.w  #0x000F,drDATA
  2768.     or.w    drEA,drDATA
  2769.     not.w   drDATA
  2770.     move.b  drDATA,(arEA)
  2771.     rts
  2772.  
  2773. rsPIA01:
  2774.     ; joystick stuff
  2775.     move.l  drEA,arEA
  2776.     tst.w   fAtariXL
  2777.     bne.s   rsPIA01XL
  2778.     
  2779.     move.w  Joy0,drDATA
  2780.     move.w  drDATA,drEA
  2781.     lsl.w   #4,drEA
  2782.     lsr.w   #8,drDATA
  2783.     andi.w  #0x00F0,drEA
  2784.     andi.w  #0x000F,drDATA
  2785.     or.w    drEA,drDATA
  2786.     not.w   drDATA
  2787.     move.b  drDATA,(arEA)
  2788. rsPIA01_x:
  2789.     rts
  2790. rsPIA01XL:
  2791.     ori.w   #0x00FC,drEA
  2792.     move.l  drEA,arEA
  2793.     bra     rsPIA01_x
  2794.  
  2795. rsPIA02:
  2796.     move.b  #0x00,(arEA)
  2797.     rts
  2798. rsPIA03:
  2799.     move.b  #0x00,(arEA)
  2800.     rts
  2801.  
  2802. rsGTIA00:
  2803.     andi.w  #0xFF1F,drEA
  2804.     move.l  drEA,arEA
  2805.     move.b  #0x00,(arEA)
  2806.     rts
  2807. rsGTIA01:
  2808.     andi.w  #0xFF1F,drEA
  2809.     move.l  drEA,arEA
  2810.     move.b  #0x00,(arEA)
  2811.     rts
  2812. rsGTIA02:
  2813.     andi.w  #0xFF1F,drEA
  2814.     move.l  drEA,arEA
  2815.     move.b  #0x00,(arEA)
  2816.     rts
  2817. rsGTIA03:
  2818.     andi.w  #0xFF1F,drEA
  2819.     move.l  drEA,arEA
  2820.     move.b  #0x00,(arEA)
  2821.     rts
  2822. rsGTIA04:
  2823.     andi.w  #0xFF1F,drEA
  2824.     move.l  drEA,arEA
  2825.     move.b  #0x00,(arEA)
  2826.     rts
  2827. rsGTIA05:
  2828.     andi.w  #0xFF1F,drEA
  2829.     move.l  drEA,arEA
  2830.     move.b  #0x00,(arEA)
  2831.     rts
  2832. rsGTIA06:
  2833.     andi.w  #0xFF1F,drEA
  2834.     move.l  drEA,arEA
  2835.     move.b  #0x00,(arEA)
  2836.     rts
  2837. rsGTIA07:
  2838.     andi.w  #0xFF1F,drEA
  2839.     move.l  drEA,arEA
  2840.     move.b  #0x00,(arEA)
  2841.     rts
  2842. rsGTIA08:
  2843.     andi.w  #0xFF1F,drEA
  2844.     move.l  drEA,arEA
  2845.     move.b  #0x00,(arEA)
  2846.     rts
  2847. rsGTIA09:
  2848.     andi.w  #0xFF1F,drEA
  2849.     move.l  drEA,arEA
  2850.     move.b  #0x00,(arEA)
  2851.     rts
  2852. rsGTIA0A:
  2853.     andi.w  #0xFF1F,drEA
  2854.     move.l  drEA,arEA
  2855.     move.b  #0x00,(arEA)
  2856.     rts
  2857. rsGTIA0B:
  2858.     andi.w  #0xFF1F,drEA
  2859.     move.l  drEA,arEA
  2860.     move.b  #0x00,(arEA)
  2861.     rts
  2862. rsGTIA0C:
  2863.     andi.w  #0xFF1F,drEA
  2864.     move.l  drEA,arEA
  2865.     move.b  #0x00,(arEA)
  2866.     rts
  2867. rsGTIA0D:
  2868.     andi.w  #0xFF1F,drEA
  2869.     move.l  drEA,arEA
  2870.     move.b  #0x00,(arEA)
  2871.     rts
  2872. rsGTIA0E:
  2873.     andi.w  #0xFF1F,drEA
  2874.     move.l  drEA,arEA
  2875.     move.b  #0x00,(arEA)
  2876.     rts
  2877. rsGTIA0F:
  2878.     andi.w  #0xFF1F,drEA
  2879.     move.l  drEA,arEA
  2880.     move.b  #0x00,(arEA)
  2881.     rts
  2882.  
  2883. ; $D010 TRIG0
  2884. rsGTIA10:
  2885.     andi.w  #0xFF1F,drEA
  2886.     move.l  drEA,arEA
  2887.     move.b  Joy0,drDATA
  2888.     lsr.b   #7,drDATA
  2889.     not.w   drDATA
  2890.     andi.w  #1,drDATA
  2891.     move.b  drDATA,(arEA)
  2892.     rts
  2893.  
  2894. ; $D011 TRIG1
  2895. rsGTIA11:
  2896.     andi.w  #0xFF1F,drEA
  2897.     move.l  drEA,arEA
  2898.     move.w  Joy0,drDATA
  2899.     lsr.b   #7,drDATA
  2900.     not.w   drDATA
  2901.     andi.w  #1,drDATA
  2902.     move.b  drDATA,(arEA)
  2903.     rts
  2904.  
  2905. ; $D012 TRIG2
  2906. rsGTIA12:
  2907.     andi.w  #0xFF1F,drEA
  2908.     move.l  drEA,arEA
  2909.     move.b  Joy0,drDATA
  2910.     lsr.b   #7,drDATA
  2911.     not.w   drDATA
  2912.     andi.w  #1,drDATA
  2913.     move.b  drDATA,(arEA)
  2914.     rts
  2915.  
  2916. ; $D013 TRIG3
  2917. rsGTIA13:
  2918.     andi.w  #0xFF1F,drEA
  2919.     move.l  drEA,arEA
  2920.     move.w  Joy0,drDATA
  2921.     lsr.b   #7,drDATA
  2922.     not.w   drDATA
  2923.     andi.w  #1,drDATA
  2924.     move.b  drDATA,(arEA)
  2925.     rts
  2926.  
  2927. ; PAL - return US TV = $0E
  2928. rsGTIA14:
  2929.     andi.w  #0xFF1F,drEA
  2930.     move.l  drEA,arEA
  2931.     move.b  #0x0E,(arEA)
  2932.     rts
  2933.  
  2934. ; unused on 8 bit, normally returns $0F - use as Xformer detect byte    
  2935. rsGTIA15:
  2936.     andi.w  #0xFF1F,drEA
  2937.     move.l  drEA,arEA
  2938.     move.b  #0xC0,(arEA)
  2939.     rts
  2940.  
  2941. rsGTIA16:
  2942.     andi.w  #0xFF1F,drEA
  2943.     move.l  drEA,arEA
  2944.     move.b  #0xFF,(arEA)
  2945.     rts
  2946. rsGTIA17:
  2947.     andi.w  #0xFF1F,drEA
  2948.     move.l  drEA,arEA
  2949.     move.b  #0xFF,(arEA)
  2950.     rts
  2951. rsGTIA18:
  2952.     andi.w  #0xFF1F,drEA
  2953.     move.l  drEA,arEA
  2954.     move.b  #0xFF,(arEA)
  2955.     rts
  2956. rsGTIA19:
  2957.     andi.w  #0xFF1F,drEA
  2958.     move.l  drEA,arEA
  2959.     move.b  #0xFF,(arEA)
  2960.     rts
  2961. rsGTIA1A:
  2962.     andi.w  #0xFF1F,drEA
  2963.     move.l  drEA,arEA
  2964.     move.b  #0xFF,(arEA)
  2965.     rts
  2966. rsGTIA1B:
  2967.     andi.w  #0xFF1F,drEA
  2968.     move.l  drEA,arEA
  2969.     move.b  #0xFF,(arEA)
  2970.     rts
  2971. rsGTIA1C:
  2972.     andi.w  #0xFF1F,drEA
  2973.     move.l  drEA,arEA
  2974.     move.b  #0xFF,(arEA)
  2975.     rts
  2976. rsGTIA1D:
  2977.     andi.w  #0xFF1F,drEA
  2978.     move.l  drEA,arEA
  2979.     move.b  #0xFF,(arEA)
  2980.     rts
  2981. rsGTIA1E:
  2982.     andi.w  #0xFF1F,drEA
  2983.     move.l  drEA,arEA
  2984.     move.b  #0xFF,(arEA)
  2985.     rts
  2986.  
  2987. ; $D01F CONSOL - set by keyboard interrupt
  2988. rsGTIA1F:
  2989.     andi.w  #0xFF1F,drEA
  2990.     move.l  drEA,arEA
  2991.     rts
  2992.  
  2993. ; $D200-$D207 = paddle values
  2994. rsPOK00:
  2995.     andi.w  #0xFF0F,drEA
  2996.     move.l  drEA,arEA
  2997.     move.b  #228,(arEA)
  2998.     rts
  2999. rsPOK01:
  3000.     andi.w  #0xFF0F,drEA
  3001.     move.l  drEA,arEA
  3002.     move.b  #228,(arEA)
  3003.     rts
  3004. rsPOK02:
  3005.     andi.w  #0xFF0F,drEA
  3006.     move.l  drEA,arEA
  3007.     move.b  #228,(arEA)
  3008.     rts
  3009. rsPOK03:
  3010.     andi.w  #0xFF0F,drEA
  3011.     move.l  drEA,arEA
  3012.     move.b  #228,(arEA)
  3013.     rts
  3014. rsPOK04:
  3015.     andi.w  #0xFF0F,drEA
  3016.     move.l  drEA,arEA
  3017.     move.b  #228,(arEA)
  3018.     rts
  3019. rsPOK05:
  3020.     andi.w  #0xFF0F,drEA
  3021.     move.l  drEA,arEA
  3022.     move.b  #228,(arEA)
  3023.     rts
  3024. rsPOK06:
  3025.     andi.w  #0xFF0F,drEA
  3026.     move.l  drEA,arEA
  3027.     move.b  #228,(arEA)
  3028.     rts
  3029. rsPOK07:
  3030.     andi.w  #0xFF0F,drEA
  3031.     move.l  drEA,arEA
  3032.     move.b  #228,(arEA)
  3033.     rts
  3034.     
  3035. rsPOK08:
  3036.     andi.w  #0xFF0F,drEA
  3037.     move.l  drEA,arEA
  3038.     move.b  #0xFF,(arEA)
  3039.     rts
  3040.  
  3041. ; $D209 KBCODE - keyboard code, set by keyboard interrupt 
  3042. rsPOK09:
  3043.     andi.w  #0xFF0F,drEA
  3044.     move.l  drEA,arEA
  3045.     rts
  3046.  
  3047. ; $D20A - random number generator
  3048. rsPOK0A:
  3049.     andi.w  #0xFF0F,drEA
  3050.     move.l  drEA,arEA
  3051.     move.b  0x465,drDATA
  3052.     or.b    Joy0,drDATA
  3053.     add.b   0x8209,drDATA
  3054.     move.b  drDATA,(arEA)
  3055.     rts
  3056.  
  3057. rsPOK0B:
  3058.     andi.w  #0xFF0F,drEA
  3059.     move.l  drEA,arEA
  3060.     move.b  #0xFF,(arEA)
  3061.     rts
  3062. rsPOK0C:
  3063.     andi.w  #0xFF0F,drEA
  3064.     move.l  drEA,arEA
  3065.     move.b  #0xFF,(arEA)
  3066.     rts
  3067. rsPOK0D:
  3068.     andi.w  #0xFF0F,drEA
  3069.     move.l  drEA,arEA
  3070.     move.b  #0xFF,(arEA)
  3071.     rts
  3072.  
  3073. ; $D20E - IRQ status, altered by interrupt handler
  3074. rsPOK0E:
  3075.     andi.w  #0xFF0F,drEA
  3076.     move.l  drEA,arEA
  3077.     move.b  bIRQ(arEMUL),drDATA     ; IRQ status is active low
  3078.     not.b   drDATA
  3079.     move.b  drDATA,(arEA)           ; stuff in IRQ status
  3080.     rts
  3081.  
  3082. ; $D20F - SKSTAT - already set from interrupt code and $D20A
  3083. rsPOK0F:
  3084.     andi.w  #0xFF0F,drEA
  3085.     move.l  drEA,arEA
  3086.     rts
  3087.  
  3088. rsANT00:
  3089.     andi.w  #0xFF0F,drEA
  3090.     move.l  drEA,arEA
  3091.     move.b  #0xFF,(arEA)
  3092.     rts
  3093. rsANT01:
  3094.     andi.w  #0xFF0F,drEA
  3095.     move.l  drEA,arEA
  3096.     move.b  #0xFF,(arEA)
  3097.     rts
  3098. rsANT02:
  3099.     andi.w  #0xFF0F,drEA
  3100.     move.l  drEA,arEA
  3101.     move.b  #0xFF,(arEA)
  3102.     rts
  3103. rsANT03:
  3104.     andi.w  #0xFF0F,drEA
  3105.     move.l  drEA,arEA
  3106.     move.b  #0xFF,(arEA)
  3107.     rts
  3108. rsANT04:
  3109.     andi.w  #0xFF0F,drEA
  3110.     move.l  drEA,arEA
  3111.     move.b  #0xFF,(arEA)
  3112.     rts
  3113. rsANT05:
  3114.     andi.w  #0xFF0F,drEA
  3115.     move.l  drEA,arEA
  3116.     move.b  #0xFF,(arEA)
  3117.     rts
  3118. rsANT06:
  3119.     andi.w  #0xFF0F,drEA
  3120.     move.l  drEA,arEA
  3121.     move.b  #0xFF,(arEA)
  3122.     rts
  3123. rsANT07:
  3124.     andi.w  #0xFF0F,drEA
  3125.     move.l  drEA,arEA
  3126.     move.b  #0xFF,(arEA)
  3127.     rts
  3128. rsANT08:
  3129.     andi.w  #0xFF0F,drEA
  3130.     move.l  drEA,arEA
  3131.     move.b  #0xFF,(arEA)
  3132.     rts
  3133. rsANT09:
  3134.     andi.w  #0xFF0F,drEA
  3135.     move.l  drEA,arEA
  3136.     move.b  #0xFF,(arEA)
  3137.     rts
  3138.  
  3139. ; $D40A - WSYNC
  3140. rsANT0A:
  3141.     muls    D0,D0
  3142.     muls    D0,D0
  3143.     muls    D0,D0
  3144.     andi.w  #0xFF0F,drEA
  3145.     move.l  drEA,arEA
  3146.     move.b  #0xFF,(arEA)
  3147.     rts
  3148.  
  3149. ; $D40B - VCOUNT
  3150. rsANT0B:
  3151.     andi.w  #0xFF0F,drEA
  3152.     move.l  drEA,arEA
  3153.     move.b  0x8207,-(SP)
  3154.     move.w  (SP)+,drDATA
  3155.     move.b  0x8209,drDATA
  3156.     andi.l  #0x00007FFF,drDATA
  3157.     divu    #293,drDATA
  3158.     add.w   #16,drDATA
  3159.     move.b  drDATA,(arEA)
  3160.     rts
  3161.  
  3162. rsANT0C:
  3163.     andi.w  #0xFF0F,drEA
  3164.     move.l  drEA,arEA
  3165.     move.b  #0xFF,(arEA)
  3166.     rts
  3167. rsANT0D:
  3168.     andi.w  #0xFF0F,drEA
  3169.     move.l  drEA,arEA
  3170.     move.b  #0xFF,(arEA)
  3171.     rts
  3172. rsANT0E:
  3173.     andi.w  #0xFF0F,drEA
  3174.     move.l  drEA,arEA
  3175.     move.b  #0xFF,(arEA)
  3176.     rts
  3177. rsANT0F:
  3178.     andi.w  #0xFF0F,drEA
  3179.     move.l  drEA,arEA
  3180.     move.b  bNMI(arEMUL),(arEA)     ; stuff in NMI status
  3181.     rts
  3182.  
  3183. rsBXX:
  3184.     rts
  3185.  
  3186.  
  3187. ; This is the 6502 interrupt handler.
  3188. ; It determines what the interrupt is, sets appropriate hardware registers
  3189. ; and jumps through $FFFE if it is an IRQ, or $FFFA is it is a NMI
  3190.  
  3191. #ifdef DEBUG
  3192.     dc.w    'At', 'ar', 'iI', 'nt', 0
  3193. #endif
  3194.  
  3195. LAtariInt:
  3196.     move.w  #OP_EMUL,(arEMUL)   ; restore dispatcher    
  3197.  
  3198.     move.b  bNMI(arEMUL),D0     ; get interrupt byte
  3199.     beq     LtryIRQ             ; branch to IRQ if NMI is zero
  3200.  
  3201.  
  3202. ; it is a NMI
  3203.  
  3204. #ifdef NDEBUG
  3205.     move.l  lScr,arEA
  3206.     move.b  D0,5(arEA)
  3207.     move.b  D0,85(arEA)
  3208.     move.b  D0,165(arEA)
  3209.     move.b  D0,245(arEA)
  3210.     move.b  D0,325(arEA)
  3211.     move.b  D0,405(arEA)
  3212.     st      485(arEA)
  3213. #endif
  3214.  
  3215.     bsr     LPush               ; save P and PC
  3216.     st      bI(arEMUL)          ; turn on I flag
  3217.  
  3218. #ifdef NDEBUG
  3219.     move.l  lScr,arEA
  3220.     not     2(arEA)
  3221.     not     82(arEA)
  3222.     not     162(arEA)
  3223.     not     242(arEA)
  3224.     not     322(arEA)
  3225.     not     402(arEA)
  3226. #endif
  3227.  
  3228.     move.w  #0xFFFA,drEA
  3229.     move.l  drEA,arPC
  3230.     jmp     0x4C06(arEMUL)      ; jmp($FFFA)
  3231.     
  3232.  
  3233. ; it is an IRQ
  3234.  
  3235. LtryIRQ:
  3236.     move.b  bIRQ(arEMUL),D0     ; get interrupt byte
  3237.     beq     LexitInt            ; exit if not IRQ????
  3238.  
  3239. #ifdef NDEBUG
  3240.     move.l  lScr,arEA
  3241.     move.b  D0,6(arEA)
  3242.     move.b  D0,86(arEA)
  3243.     move.b  D0,166(arEA)
  3244.     move.b  D0,246(arEA)
  3245.     move.b  D0,326(arEA)
  3246.     move.b  D0,406(arEA)
  3247.     st      486(arEA)
  3248. #endif
  3249.  
  3250.     bsr     LPush               ; save P and PC
  3251.     st      bI(arEMUL)          ; turn on I flag
  3252.  
  3253.     move.w  #0xFFFE,drEA
  3254.     move.l  drEA,arPC
  3255.     jmp     0x4C06(arEMUL)      ; jmp($FFFE)
  3256.  
  3257. LexitInt:
  3258. #ifdef NDEBUG
  3259.     move.l  lScr,arEA
  3260.     not     52(arEA)
  3261.     not     132(arEA)
  3262.     not     212(arEA)
  3263.     not     292(arEA)
  3264.     not     372(arEA)
  3265.     not     452(arEA)
  3266. #endif
  3267.     DISPATCH
  3268.  
  3269. LPush:
  3270.     subq.b  #3,drSP
  3271.     move.l  drSP,arEA
  3272.     move.l  arPC,drEA
  3273.     move.b  drEA,2(arEA)        ; push PClo
  3274.     lsr.w   #8,drEA
  3275.     move.b  drEA,3(arEA)        ; push PChi
  3276.     ST_to_P
  3277.     move.b  bRegP(arEMUL),1(arEA)   ; push P
  3278.     rts
  3279.  
  3280. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3281. ; This is the VBI routine
  3282. ; Force a NMI interrupt on the 6502
  3283. ; and update any hardware registers we can, like joysticks, etc...
  3284. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3285.  
  3286. #ifdef DEBUG
  3287.     dc.w    'At', 'ar', 'iV', 'BI', 0
  3288. #endif
  3289.  
  3290. Lmod:
  3291.     dc.w    0
  3292.  
  3293. LAtariVBI:
  3294.     lea     0x8800,A0
  3295.     lea     rgbSound,A1
  3296.     moveq   #3,D7       ; count of available sound registers
  3297.     move.w  #0xFF,D6    ; sound enable mask
  3298.     move.b  8(A1),D5    ; audio control register
  3299.     
  3300. LdoS1:
  3301.     moveq   #0,D0
  3302.     move.b  (A1)+,D0    ; get freq #1
  3303.     move.b  (A1)+,D1    ; get volume #1
  3304.     move.b  D1,D2
  3305.     tst.b   D0
  3306.     beq     LdoS2
  3307.     
  3308.     andi.w  #0x0F,D2    ; isolate volume
  3309.     andi.w  #0xA0,D1    ; check distortion or pure tone
  3310.     cmpi.w  #0xA0,D1
  3311.     bne     LdoS1D
  3312.    
  3313.     add.w   D0,D0       ; do pure tone
  3314.     add.w   D0,D0       ; multiply freq by 4
  3315.     move.b  #0,(A0)
  3316.     move.b  D0,2(A0)
  3317.     lsr.w   #8,D0
  3318.     move.b  #1,(A0)
  3319.     move.b  D0,2(A0)
  3320.  
  3321.     move.b  #8,(A0)     ; volume voice #0
  3322.     move.b  D2,2(A0)
  3323.     andi.b  #0xFE,D6    ; enable voice #0
  3324.     bra     LdoS2
  3325.     
  3326. LdoS1D:
  3327.     lsr.b   #2,D0       ; do distortion
  3328.     move.b  #6,(A0)
  3329.     move.b  D0,2(A0)
  3330.  
  3331.     move.b  #8,(A0)     ; volume voice #0
  3332.     move.b  D2,2(A0)
  3333.     andi.b  #0xF7,D6    ; enable noise #0
  3334.      
  3335. LdoS2:
  3336.     moveq   #0,D0
  3337.     move.b  (A1)+,D0    ; get freq #2
  3338.     move.b  (A1)+,D1    ; get volume #2
  3339.     move.b  D1,D2
  3340.     tst.b   D0
  3341.     beq     LdoS3
  3342.     
  3343.     andi.w  #0x0F,D2    ; isolate volume
  3344.     andi.w  #0xA0,D1    ; check distortion or pure tone
  3345.     cmpi.w  #0xA0,D1
  3346.     bne     LdoS2D
  3347.    
  3348.     add.w   D0,D0       ; do pure tone
  3349.     add.w   D0,D0       ; multiply freq by 4
  3350.     move.b  #2,(A0)
  3351.     move.b  D0,2(A0)
  3352.     lsr.w   #8,D0
  3353.     move.b  #3,(A0)
  3354.     move.b  D0,2(A0)
  3355.  
  3356.     move.b  #9,(A0)     ; volume voice B
  3357.     move.b  D2,2(A0)
  3358.     andi.b  #0xFD,D6    ; enable voice B
  3359.     bra     LdoS3
  3360.     
  3361. LdoS2D:
  3362.     lsr.b   #2,D0       ; do distortion
  3363.     move.b  #6,(A0)
  3364.     move.b  D0,2(A0)
  3365.  
  3366.     move.b  #9,(A0)     ; volume voice B
  3367.     move.b  D2,2(A0)
  3368.     andi.b  #0xEF,D6    ; enable noise B
  3369.     
  3370. LdoS3:
  3371.     moveq   #0,D0
  3372.     move.b  (A1)+,D0    ; get freq #3
  3373.     move.b  (A1)+,D1    ; get volume #3
  3374.     move.b  D1,D2
  3375.     tst.b   D0
  3376.     beq     LdoS4
  3377.     
  3378.     andi.w  #0x0F,D2    ; isolate volume
  3379.     andi.w  #0xA0,D1    ; check distortion or pure tone
  3380.     cmpi.w  #0xA0,D1
  3381.     bne     LdoS3D
  3382.    
  3383.     add.w   D0,D0       ; do pure tone
  3384.     add.w   D0,D0       ; multiply freq by 4
  3385.     move.b  #4,(A0)
  3386.     move.b  D0,2(A0)
  3387.     lsr.w   #8,D0
  3388.     move.b  #5,(A0)
  3389.     move.b  D0,2(A0)
  3390.  
  3391.     move.b  #10,(A0)     ; volume voice C
  3392.     move.b  D2,2(A0)
  3393.     andi.b  #0xFB,D6    ; enable voice C
  3394.     bra     LdoS
  3395.     
  3396. LdoS3D:
  3397.     lsr.b   #2,D0       ; do distortion
  3398.     move.b  #6,(A0)
  3399.     move.b  D0,2(A0)
  3400.  
  3401.     move.b  #10,(A0)     ; volume voice C
  3402.     move.b  D2,2(A0)
  3403.     andi.b  #0xDF,D6    ; enable noise C
  3404.     bra     LdoS
  3405.     
  3406. LdoS4:
  3407. ;    ori.b   #0x24,D6    ; turn off C noise (keyclick)
  3408.  
  3409. LdoS:
  3410.     move.b  #7,(A0)     ; store voice enable bits
  3411.     move.b  D6,2(A0)
  3412.  
  3413. LVBI2:
  3414.     addq.w  #1,wVBIcount
  3415.     move.w  wVBIcount,D0
  3416.     cmp.w   wVBIrate,D0
  3417.     bne     LAtVBIexit      ; skip wVBIrate VBI's
  3418.  
  3419.     clr.w   wVBIcount
  3420.  
  3421.     tst.b   fXLRAM          ; are we bank selected?
  3422.     bne     LAtVBIexit      ; yep, exit
  3423.  
  3424.     move.l  lMemory,D0
  3425.     move.w  #0xD4FE,D0
  3426.     move.l  D0,A0
  3427.     btst    #BIT_VBI,(A0)       ; check if VBIs enabled
  3428.     beq     LAtVBIexit
  3429.  
  3430.     move.l  lEmul,A0
  3431.     bset    #BIT_VBI,bNMI(A0)   ; set a NMI interrupt
  3432.     bne     LAtVBIexit          ; exit if already set
  3433.  
  3434.     move.w  #OP_INT,(A0)
  3435.  
  3436. LAtVBIexit:
  3437.     lea     Lmod(PC),A0
  3438.     addi.w  #1,(A0)
  3439.     move.w  (A0),D0
  3440.     cmpi.w  #13,D0
  3441.     bcs     LAV2
  3442.  
  3443.     clr.w   (A0)
  3444.  
  3445. #ifdef NDEBUG
  3446.     move.l  lScr,arEA
  3447.     not.b   (arEA)
  3448.     not.b   84(arEA)
  3449.     not.b   164(arEA)
  3450.     not.b   244(arEA)
  3451.     not.b   324(arEA)
  3452.     not.b   404(arEA)
  3453. #endif
  3454.  
  3455.     tst.w   fRedraw             ; if fRedraw then go do a global screen redraw
  3456.     beq     LAV3                ; go test PMG redraw
  3457.  
  3458.     tst.w   fAtDMA              ; if DMA disabled, get out
  3459.     beq     LAV2
  3460.  
  3461.     movem.l D0-D7/A0-A6,-(SP)
  3462.     jsr     AtariRedraw
  3463.     movem.l (SP)+,D0-D7/A0-A6
  3464.     clr.w   fRedraw
  3465.     bra     LAV2
  3466.  
  3467. LAV3:
  3468.     tst.w   fPMGRedraw
  3469.     beq     LAV2
  3470.  
  3471.     movem.l D0-D7/A0-A6,-(SP)
  3472.     jsr     redraw_PMG
  3473.     movem.l (SP)+,D0-D7/A0-A6
  3474.     clr.w   fPMGRedraw
  3475.     
  3476. LAV2:
  3477.     rts
  3478.  
  3479.  
  3480. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3481. ;
  3482. ; Keyboard handler to map the ST scan code to an 8 bit internal scan code.
  3483. ;
  3484. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3485.  
  3486. ; some safety room
  3487.     dc.w    0
  3488.  
  3489. #ifdef DEBUG
  3490.     dc.w    'Ke', 'yP', 'at', 'ch', 0
  3491. #endif
  3492.  
  3493. Joy0:
  3494.     dc.w    0
  3495. semaJoy:
  3496.     dc.w    0
  3497.  
  3498. KeyPatch:
  3499.  
  3500. ; A1 = lScr, for debugging purposes
  3501.     movem.l  A0-A1/D0-D1,-(SP)
  3502.  
  3503. #ifdef DEBUG
  3504.     move.l  oldKey,A0
  3505.     jsr     (A0)
  3506. #endif
  3507.  
  3508.     clr.w   D0
  3509.     move.b  0xFC02,D0
  3510.  
  3511.     tst.w   semaJoy
  3512.     bne     LgetJoy
  3513.  
  3514.     cmpi.b  #0xF6,D0            ; check for a keypress
  3515.     bcs     Lkp1
  3516.  
  3517.     cmpi.b  #0xFE,D0            ; if not joystick event, get out
  3518.     bcs     Lkpexit
  3519.  
  3520.     not.b   D0
  3521.     andi.w  #0x01,D0
  3522.     addq.b  #1,D0
  3523.     move.w  D0,semaJoy          ; set joystick semaphore
  3524.     bra     Lkpexit             ; and go exit so next interrupt can occur
  3525.  
  3526. LgetJoy:
  3527.     move.w  semaJoy,D1
  3528.     lea     Joy0,A1
  3529.     move.b  D0,-1(A1,D1.w)      ; store joystick packet
  3530.     clr.w   semaJoy
  3531.  
  3532. #ifdef NDEBUG
  3533.     move.l  lScr,A1
  3534.     lea     32000(A1),A1
  3535.     move.b  D0,68(A1)
  3536.     move.b  D0,148(A1)
  3537.     st      228(A1)
  3538.     lea     Joy0,A0
  3539.     move.b  (A0)+,D0
  3540.     move.b  D0,308(A1)
  3541.     st      388(A1)
  3542.     move.b  (A0),D0
  3543.     move.b  D0,468(A1)
  3544.     st      548(A1)
  3545. #endif
  3546.  
  3547.     bra     Lkpexit
  3548.  
  3549. Lkp1:
  3550.     cmpi.b  #0x3F,D0
  3551.     bne     Lkp2
  3552.         
  3553.     move.l  lEmul,A0
  3554.     move.w  #OP_RTS,(A0)        ; hit F5, so exit
  3555.     bra     Lkpexit
  3556.         
  3557. Lkp2:
  3558.     cmpi.b  #0x44,D0            ; F10 key is SYSTEM RESET (always enabled)
  3559.     bne     Lkp3
  3560.  
  3561.     move.l  lEmul,A0
  3562.     bset    #BIT_RESET,bNMI(A0) ; set a NMI interrupt for the RESET key
  3563.     bne     Lkpexit             ; exit if already set
  3564.  
  3565.     move.b  bNMI(A0),D0
  3566.     andi.b  #~INT_RESET,D0      ; or if already NMI pending...
  3567.     bne     Lkpexit             ; don't alter dispatcher
  3568.  
  3569.     move.w  #OP_INT,(A0)
  3570.     bra     Lkpexit
  3571.  
  3572. Lkp3:
  3573.     cmpi.b  #0x61,D0            ; UNDO key is BREAK
  3574.     bne     Lkp4
  3575.  
  3576.     move.l  lEmul,A0
  3577.     btst    #BIT_BREAK,bIRQmask(A0)   ; check if BREAK is enabled
  3578.     beq     Lkpexit             ; exit if not
  3579.  
  3580.     bset    #BIT_BREAK,bIRQ(A0) ; set a IRQ interrupt for the BREAK key
  3581. ;    bne     Lkpexit             ; exit of already set
  3582.  
  3583.     tst.b   bI(A0)
  3584.     bne     Lkpexit             ; if I bit set...
  3585.  
  3586.     move.b  bIRQ(A0),D0
  3587.     andi.b  #~INT_BREAK,D0      ; or if already interrupt pending...
  3588. ;    bne     Lkpexit             ; don't alter dispatcher
  3589.  
  3590.     move.w  #OP_INT,(A0)
  3591.     bra     Lkpexit
  3592.  
  3593. Lkp4:
  3594. Lkp10:
  3595.     move.l  lEmul,A0
  3596.     move.l  lMemory,D1
  3597.     move.w  #0xD01F,D1
  3598.     move.l  D1,A0               ; A0 = pointer to mem[$D01F]
  3599.  
  3600.     cmpi.b  #0xC1,D0            ; F7 is START
  3601.     bne     Lkp11
  3602.  
  3603.     ori.b   #0x01,(A0)
  3604.     bra     Lkpexit  
  3605.     
  3606. Lkp11:
  3607.     cmpi.b  #0x41,D0
  3608.     bne     Lkp12
  3609.  
  3610.     andi.b  #~0x01,(A0)
  3611.     bra     Lkpexit
  3612.         
  3613. Lkp12:
  3614.     cmpi.b  #0xC2,D0            ; F8 is SELECT
  3615.     bne     Lkp13
  3616.     
  3617.     ori.b   #0x02,(A0)
  3618.     bra     Lkpexit  
  3619.     
  3620. Lkp13:
  3621.     cmpi.b  #0x42,D0
  3622.     bne     Lkp14
  3623.     
  3624.     andi.b  #~0x02,(A0)
  3625.     bra     Lkpexit
  3626.         
  3627. Lkp14:
  3628.     cmpi.b  #0xC3,D0            ; F9 is OPTION
  3629.     bne     Lkp15
  3630.     
  3631.     ori.b   #0x04,(A0)
  3632.     bra     Lkpexit  
  3633.     
  3634. Lkp15:
  3635.     cmpi.b  #0x43,D0
  3636.     bne     Lkp20
  3637.  
  3638.     andi.b  #~0x04,(A0)
  3639.     bra     Lkpexit
  3640.      
  3641. ; Check control and shift keys   
  3642. ; The byte bShift contains   b1 = control  b0 = shift key
  3643. ; The byte bShifts contains  b1 = right shift  b0 = left shift
  3644. Lkp20:
  3645.     lea     bShift(PC),A0
  3646.     cmpi.b  #0x1D,D0            ; Control key
  3647.     bne     Lkp21
  3648.  
  3649.     bset    #1,(A0)
  3650. #ifdef DEBUG
  3651.     move.b  bShift(PC),20(A1)
  3652.     move.b  bShift(PC),100(A1)
  3653.     move.b  bShift(PC),180(A1)
  3654.     st      500(A1)
  3655. #endif
  3656.     bra     Lkpexit
  3657.     
  3658. Lkp21:
  3659.     cmpi.b  #0x9D,D0            ; Control key up
  3660.     bne     Lkp22
  3661.  
  3662.     bclr    #1,(A0)
  3663. #ifdef DEBUG
  3664.     move.b  bShift(PC),20(A1)
  3665.     move.b  bShift(PC),100(A1)
  3666.     move.b  bShift(PC),180(A1)
  3667.     st      500(A1)
  3668. #endif
  3669.     bra     Lkpexit
  3670.     
  3671. Lkp22:
  3672.     lea     bShifts(PC),A0
  3673.     cmpi.b  #0x2A,D0            ; left shift down
  3674.     bne     Lkp23
  3675.     
  3676.     bset    #0,(A0)
  3677.     bra     LShifts
  3678.  
  3679. Lkp23:
  3680.     cmpi.b  #0xAA,D0            ; left shift up
  3681.     bne     Lkp24
  3682.     
  3683.     bclr    #0,(A0)
  3684.     bra     LShifts
  3685.  
  3686. Lkp24:
  3687.     cmpi.b  #0x36,D0            ; right shift down
  3688.     bne     Lkp25
  3689.     
  3690.     bset    #1,(A0)
  3691.     bra     LShifts
  3692.  
  3693. Lkp25:
  3694.     cmpi.b  #0xB6,D0            ; right shift down
  3695.     bne     Lkp30
  3696.     
  3697.     bclr    #1,(A0)
  3698.  
  3699. LShifts:
  3700.     move.b  (A0),D0             ; get shift keys status
  3701.     lea     bShift(PC),A0
  3702.     tst.b   D0                  ; any shift key pressed
  3703.     bne     lShiftDown
  3704.     bclr    #0,(A0)             ; no, clear shift bit in bShift
  3705.     bra     lSh2
  3706. lShiftDown:
  3707.     bset    #0,(A0)             ; yes, set shift but
  3708.  
  3709. lSh2:
  3710. #ifdef DEBUG
  3711.     move.b  bShift(PC),20(A1)
  3712.     move.b  bShift(PC),100(A1)
  3713.     move.b  bShift(PC),180(A1)
  3714.     move.b  bShifts(PC),260(A1)
  3715.     move.b  bShifts(PC),340(A1)
  3716.     move.b  bShifts(PC),420(A1)
  3717.     st      500(A1)
  3718. #endif
  3719.     bra     Lkpexit
  3720.     
  3721. Lkp30:
  3722.     move.b  #0xFF,D1            ; assume scan code will be $FF
  3723.     btst    #7,D0               ; if up stroke, definately $FF
  3724.     bne     lStoreKey
  3725.     
  3726.     andi.w  #0x7F,D0                    ; else key pressed, look up in table
  3727.     add.w   D0,D0
  3728.     add.w   D0,D0
  3729.     or.b    bShift(PC),D0
  3730.     lea     mpSTto8(PC),A0
  3731.     move.b  0(A0,D0.w),D1
  3732.     
  3733. #ifdef DEBUG
  3734.     move.w  D0,10(A1)
  3735.     move.w  D0,90(A1)
  3736.     move.w  D0,170(A1)
  3737.     move.w  D0,250(A1)
  3738.     st      330(A1)
  3739.     st      411(A1)
  3740. #endif
  3741.  
  3742. lStoreKey:
  3743.     move.l  lEmul,A0                    ; get pointer to mem[$D209]
  3744.     move.l  lMemory,D0
  3745.     move.w  #0xD209,D0
  3746.     move.l  D0,A0
  3747.     move.b  D1,(A0)                     ; and store scan code
  3748.  
  3749. #ifdef DEBUG
  3750.     move.b  D1,13(A1)
  3751.     move.b  D1,93(A1)
  3752.     move.b  D1,173(A1)
  3753.     move.b  D1,253(A1)
  3754.     move.b  D1,333(A1)
  3755.     st      413(A1)
  3756. #endif
  3757.  
  3758. ; set bits in $D20F
  3759.     move.w  #0xD20F,D0
  3760.     move.l  D0,A0
  3761.     move.b  bShift(PC),D0
  3762.     btst    #0,D0
  3763.     beq     lShiftUp
  3764.     bclr    #3,(A0)         ; shift key still pressed
  3765.     bra     lSK2
  3766. lShiftUp:
  3767.     bset    #3,(A0)
  3768.  
  3769. lSK2:
  3770.     cmpi.b  #0xFF,D1
  3771.     beq     lKeyUp     
  3772.     bclr    #2,(A0)         ; key still pressed
  3773.     
  3774. ; if key just pressed, force IRQ
  3775.     move.l  lEmul,A0
  3776.     btst    #BIT_KEY,bIRQmask(A0)   ; check if keyboard int enabled
  3777.     beq     lSK3                ; exit if not
  3778.  
  3779.     bset    #BIT_KEY,bIRQ(A0)   ; set a IRQ interrupt for the key
  3780. ;    bne     lSK3                ; exit if already set
  3781.  
  3782.     tst.b   bI(A0)
  3783.     bne     lSK3                ; if I bit set...
  3784.  
  3785.     move.b  bIRQ(A0),D0
  3786.     andi.b  #~INT_KEY,D0        ; or if already interrupt pending...
  3787. ;    bne     lSK3                ; don't alter dispatcher
  3788.  
  3789.     move.w  #OP_INT,(A0)
  3790.     bra     lSK3
  3791.  
  3792. lKeyUp:
  3793.     bset    #2,(A0)
  3794.  
  3795. lSK3:
  3796.     nop
  3797.  
  3798. Lkpexit:
  3799.     movem.l  (SP)+,A0-A1/D0-D1
  3800.     rts
  3801.  
  3802. oldKey:
  3803.     dc.l    0
  3804.  
  3805. bShift:
  3806.     dc.w    0           ; bit 0 = any shift    bit 1 = control
  3807. bShifts:
  3808.     dc.w    0           ; bit 0 = left shift   bit 1 = right shift
  3809.  
  3810.     
  3811. ; Lookup table to map the ST's scan codes to the 8 bit internal code
  3812. ; Keys that do not apply map to $FF
  3813. ; There are 4 entries per line, regular, shift, control, control shift
  3814.  
  3815.     dc.w    'KB', 'DT', 'BL', 0
  3816.  
  3817. mpSTto8:
  3818.     dc.w    0xFFFF, 0xFFFF      ; $00           
  3819.     dc.w    0x1C5C, 0x9CDC      ; $01 Esc       
  3820.     dc.w    0x1F5F, 0x9FDF      ; $02 1         
  3821.     dc.w    0x1E75, 0x9EDE      ; $03 2 map to @ not "
  3822.     dc.w    0x1A5A, 0x9ADA      ; $04 3         
  3823.     dc.w    0x1858, 0x98D8      ; $05 4         
  3824.     dc.w    0x1D5D, 0x9DDD      ; $06 5         
  3825.     dc.w    0x1B47, 0x9BDB      ; $07 6 map to ^ not &
  3826.     dc.w    0x335B, 0xB3F3      ; $08 7 map to & not '
  3827.     dc.w    0x3507, 0xB5F5      ; $09 8 map to * not @
  3828.     dc.w    0x3070, 0xB0F0      ; $0A 9         
  3829.     dc.w    0x3272, 0xB2F2      ; $0B 0         
  3830.     dc.w    0x0E4E, 0x8ECE      ; $0C -         
  3831.     dc.w    0x0F06, 0x8FCF      ; $0D =         
  3832.     dc.w    0x3474, 0xB4F4      ; $0E Backspace 
  3833.     dc.w    0x2C6C, 0xACEC      ; $0F Tab       
  3834.     dc.w    0x2F6F, 0xAFEF      ; $10 q         
  3835.     dc.w    0x2E6E, 0xAEEE      ; $11 w         
  3836.     dc.w    0x2A6A, 0xAAEA      ; $12 e         
  3837.     dc.w    0x2868, 0xA8E8      ; $13 r         
  3838.     dc.w    0x2D6D, 0xADED      ; $14 t         
  3839.     dc.w    0x2B6B, 0xABEB      ; $15 y         
  3840.     dc.w    0x0B4B, 0x8BCB      ; $16 u         
  3841.     dc.w    0x0D4D, 0x8DCD      ; $17 i         
  3842.     dc.w    0x0848, 0x88C8      ; $18 o         
  3843.     dc.w    0x0A4A, 0x8ACA      ; $19 p         
  3844.     dc.w    0x6060, 0xA0E0      ; $1A [         
  3845.     dc.w    0x6262, 0xA2E2      ; $1B ]         
  3846.     dc.w    0x0C4C, 0x8CCC      ; $1C Return    
  3847.     dc.w    0xFFFF, 0xFFFF      ; $1D Control   
  3848.     dc.w    0x3F7F, 0xBFFF      ; $1E a         
  3849.     dc.w    0x3E7E, 0xBEFE      ; $1F s         
  3850.     dc.w    0x3A7A, 0xBAFA      ; $20 d         
  3851.     dc.w    0x3878, 0xB8F8      ; $21 f         
  3852.     dc.w    0x3D7D, 0xB8F8      ; $22 g         
  3853.     dc.w    0x3979, 0xB9F9      ; $23 h         
  3854.     dc.w    0x0141, 0x81C1      ; $24 j         
  3855.     dc.w    0x0545, 0x85C5      ; $25 k         
  3856.     dc.w    0x0040, 0x80C0      ; $26 l         
  3857.     dc.w    0x0242, 0x82C2      ; $27 ;         
  3858.     dc.w    0x735E, 0xB3F3      ; $28 ' map to " not 7
  3859.     dc.w    0xFFFF, 0xFFFF      ; $29 `         
  3860.     dc.w    0xFFFF, 0xFFFF      ; $2A l shift
  3861.     dc.w    0x664F, 0xE6E6      ; $2B \         
  3862.     dc.w    0x1757, 0x97D7      ; $2C z         
  3863.     dc.w    0x1656, 0x96D6      ; $2D x         
  3864.     dc.w    0x1252, 0x92D2      ; $2E c         
  3865.     dc.w    0x1050, 0x90D0      ; $2F v         
  3866.     dc.w    0x1555, 0x95D5      ; $30 b         
  3867.     dc.w    0x2363, 0xA3E3      ; $31 n         
  3868.     dc.w    0x2565, 0xA5E5      ; $32 m         
  3869.     dc.w    0x2037, 0xA0E0      ; $33 ,         
  3870.     dc.w    0x2236, 0xA2E2      ; $34 .         
  3871.     dc.w    0x2666, 0xA6E6      ; $35 /         
  3872.     dc.w    0xFFFF, 0xFFFF      ; $36 r shift   
  3873.     dc.w    0xFFFF, 0xFFFF      ; $37           
  3874.     dc.w    0x2767, 0xA7E7      ; $38 alt = atari key
  3875.     dc.w    0x2161, 0xA1E1      ; $39 space     
  3876.     dc.w    0x3C7C, 0xBCFC      ; $3A caps      
  3877.     dc.w    0xFFFF, 0xFFFF      ; $3B F1        
  3878.     dc.w    0xFFFF, 0xFFFF      ; $3C F2        
  3879.     dc.w    0xFFFF, 0xFFFF      ; $3D F3        
  3880.     dc.w    0xFFFF, 0xFFFF      ; $3E F4        
  3881.     dc.w    0xFFFF, 0xFFFF      ; $3F F5        
  3882.     dc.w    0xFFFF, 0xFFFF      ; $40 F6        
  3883.     dc.w    0xFFFF, 0xFFFF      ; $41 F7        
  3884.     dc.w    0xFFFF, 0xFFFF      ; $42 F8        
  3885.     dc.w    0xFFFF, 0xFFFF      ; $43 F9        
  3886.     dc.w    0xFFFF, 0xFFFF      ; $44 F10       
  3887.     dc.w    0xFFFF, 0xFFFF      ; $45           
  3888.     dc.w    0xFFFF, 0xFFFF      ; $46           
  3889.     dc.w    0x7676, 0xB6F6      ; $47 Home
  3890.     dc.w    0x0E4E, 0x8ECE      ; $48 up arrow  
  3891.     dc.w    0xFFFF, 0xFFFF      ; $49           
  3892.     dc.w    0x0E4E, 0x8ECE      ; $4A pad -     
  3893.     dc.w    0x0646, 0x86C6      ; $4B l arrow   
  3894.     dc.w    0xFFFF, 0xFFFF      ; $4C           
  3895.     dc.w    0x0747, 0x87C7      ; $4D r arrow   
  3896.     dc.w    0x0646, 0x86C6      ; $4E pad +     
  3897.     dc.w    0xFFFF, 0xFFFF      ; $4F           
  3898.     dc.w    0x0F4F, 0x8FCF      ; $50 d arrow   
  3899.     dc.w    0xFFFF, 0xFFFF      ; $51           
  3900.     dc.w    0x3777, 0xB7F7      ; $52 Insert    
  3901.     dc.w    0x3474, 0xB4F4      ; $53 Delete    
  3902.     dc.w    0xFFFF, 0xFFFF      ; $54           
  3903.     dc.w    0xFFFF, 0xFFFF      ; $55           
  3904.     dc.w    0xFFFF, 0xFFFF      ; $56           
  3905.     dc.w    0xFFFF, 0xFFFF      ; $57           
  3906.     dc.w    0xFFFF, 0xFFFF      ; $58           
  3907.     dc.w    0xFFFF, 0xFFFF      ; $59           
  3908.     dc.w    0xFFFF, 0xFFFF      ; $5A           
  3909.     dc.w    0xFFFF, 0xFFFF      ; $5B           
  3910.     dc.w    0xFFFF, 0xFFFF      ; $5C           
  3911.     dc.w    0xFFFF, 0xFFFF      ; $5D           
  3912.     dc.w    0xFFFF, 0xFFFF      ; $5E           
  3913.     dc.w    0xFFFF, 0xFFFF      ; $5F           
  3914.     dc.w    0xFFFF, 0xFFFF      ; $60           
  3915.     dc.w    0xFFFF, 0xFFFF      ; $61 Undo      
  3916.     dc.w    0xFFFF, 0xFFFF      ; $62 Help      
  3917.     dc.w    0x7070, 0xB0F0      ; $63 pad (     
  3918.     dc.w    0x7272, 0xB2F2      ; $64 pad )     
  3919.     dc.w    0x2666, 0xA6E6      ; $65 pad /     
  3920.     dc.w    0x0747, 0x87C7      ; $66 pad *     
  3921.     dc.w    0x3373, 0xB3F3      ; $67 pad 7     
  3922.     dc.w    0x3575, 0xB5F5      ; $68 pad 8     
  3923.     dc.w    0x3070, 0xB0F0      ; $69 pad 9     
  3924.     dc.w    0x1858, 0x98D8      ; $6A pad 4     
  3925.     dc.w    0x1D5D, 0x9DDD      ; $6B pad 5     
  3926.     dc.w    0x1B5B, 0x9BDB      ; $6C pad 6     
  3927.     dc.w    0x1F5F, 0x9FDF      ; $6D pad 1     
  3928.     dc.w    0x1E5E, 0x9EDE      ; $6E pad 2     
  3929.     dc.w    0x1A5A, 0x9ADA      ; $6F pad 3     
  3930.     dc.w    0x3272, 0xB2F2      ; $70 pad 0     
  3931.     dc.w    0x2262, 0xA2E2      ; $71 pad .     
  3932.     dc.w    0x0C4C, 0x8CCC      ; $72 Enter     
  3933.     dc.w    0xFFFF, 0xFFFF      ; $73           
  3934.     dc.w    0xFFFF, 0xFFFF      ; $74           
  3935.     dc.w    0xFFFF, 0xFFFF      ; $75           
  3936.     dc.w    0xFFFF, 0xFFFF      ; $76           
  3937.     dc.w    0xFFFF, 0xFFFF      ; $77           
  3938.     dc.w    0xFFFF, 0xFFFF      ; $78           
  3939.     dc.w    0xFFFF, 0xFFFF      ; $79           
  3940.     dc.w    0xFFFF, 0xFFFF      ; $7A           
  3941.     dc.w    0xFFFF, 0xFFFF      ; $7B           
  3942.     dc.w    0xFFFF, 0xFFFF      ; $7C           
  3943.     dc.w    0xFFFF, 0xFFFF      ; $7D           
  3944.     dc.w    0xFFFF, 0xFFFF      ; $7E           
  3945.     dc.w    0xFFFF, 0xFFFF      ; $7F           
  3946.  
  3947.  
  3948.  
  3949. ; add more assembler code here:
  3950.  
  3951.     }
  3952.     }
  3953.  
  3954.